Avoid calling TextPainter.plainText for simple static text (#146084)

`InlineSpan.toPlainText` is surprisingly expensive even for a simple `TextSpan` like `TextSpan(text: 'AAA', children: [TextSpan(text: char * 10), TextSpan(text: char * 20)])` 

![image](https://github.com/flutter/flutter/assets/31859944/60014acb-78bd-4dbb-a48d-74295aeb612c)
This commit is contained in:
LongCatIsLooong 2024-04-02 22:22:56 -07:00 committed by GitHub
parent bf7deff765
commit 3295a48f17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -276,10 +276,14 @@ class _UntilTextBoundary extends TextBoundary {
} }
class _TextLayout { class _TextLayout {
_TextLayout._(this._paragraph, this.writingDirection, this.rawString); _TextLayout._(this._paragraph, this.writingDirection, this._painter);
final TextDirection writingDirection; final TextDirection writingDirection;
final String rawString;
// Computing plainText is a bit expensive and is currently not needed for
// simple static text. Pass in the entire text painter so `TextPainter.plainText`
// is only called when needed.
final TextPainter _painter;
// This field is not final because the owner TextPainter could create a new // This field is not final because the owner TextPainter could create a new
// ui.Paragraph with the exact same text layout (for example, when only the // ui.Paragraph with the exact same text layout (for example, when only the
@ -340,6 +344,7 @@ class _TextLayout {
/// line ended with a line feed. /// line ended with a line feed.
late final _LineCaretMetrics _endOfTextCaretMetrics = _computeEndOfTextCaretAnchorOffset(); late final _LineCaretMetrics _endOfTextCaretMetrics = _computeEndOfTextCaretAnchorOffset();
_LineCaretMetrics _computeEndOfTextCaretAnchorOffset() { _LineCaretMetrics _computeEndOfTextCaretAnchorOffset() {
final String rawString = _painter.plainText;
final int lastLineIndex = _paragraph.numberOfLines - 1; final int lastLineIndex = _paragraph.numberOfLines - 1;
assert(lastLineIndex >= 0); assert(lastLineIndex >= 0);
final ui.LineMetrics lineMetrics = _paragraph.getLineMetricsAt(lastLineIndex)!; final ui.LineMetrics lineMetrics = _paragraph.getLineMetricsAt(lastLineIndex)!;
@ -1189,7 +1194,7 @@ class TextPainter {
// called. // called.
final ui.Paragraph paragraph = (cachedLayout?.paragraph ?? _createParagraph(text)) final ui.Paragraph paragraph = (cachedLayout?.paragraph ?? _createParagraph(text))
..layout(ui.ParagraphConstraints(width: layoutMaxWidth)); ..layout(ui.ParagraphConstraints(width: layoutMaxWidth));
final _TextLayout layout = _TextLayout._(paragraph, textDirection, plainText); final _TextLayout layout = _TextLayout._(paragraph, textDirection, this);
final double contentWidth = layout._contentWidthFor(minWidth, maxWidth, textWidthBasis); final double contentWidth = layout._contentWidthFor(minWidth, maxWidth, textWidthBasis);
final _TextPainterLayoutCacheWithOffset newLayoutCache; final _TextPainterLayoutCacheWithOffset newLayoutCache;