Skip to content

Improve the performance of the EditableTextState / text input synchronization #113725

@gaaclarke

Description

@gaaclarke

Currently every frame the EditableTextState will calculate and send state to the text input in the following locations:

  1. SchedulerBinding.instance.addPostFrameCallback((Duration _) => _updateComposingRectIfNeeded());
  2. SchedulerBinding.instance.addPostFrameCallback((Duration _) => _updateCaretRectIfNeeded());
  3. SchedulerBinding.instance.addPostFrameCallback((Duration _) => _updateSizeAndTransform());

In the use case defined in #59327 this represents a significant portion of the ui thread's time. I implemented a naive approach that dropped the frequency of the updates and that lead to a 28% decrease in CPU usage (#113722). @LongCatIsLooong and Hixie determined there is a better way to be more reactive for sending updates so that is preferable to the naive drop in frequency. We should implement that.

Here is the chat excerpt that explains the alternative:

Hixie — Today at 2:08 PM
if you just want to know when the rect changes, the way to do that is to create a Layer
similar to how FollowerLayers work
LongCatIsLooong — Today at 2:16 PM
The rects sent to the textinputplugin are in RenderEditable coordinates so probably no layer needed? 
But EditableTextState doesn't get notified when the text layout changes so it has to poll the caret location
Hixie — Today at 2:28 PM
oh if it's RenderEditable coordinates then yeah that's even better
why doesn't the RenderEditable know when the text layout changes?
isn't it responsible for doing the layout?
LongCatIsLooong — Today at 2:37 PM
EditableTextState doesn't, the inlinespan and writing direction etc,. are handed to the underlying TextPainter and the text painter figures out whether it needs to rebuild a new ui.Paragraph. I think TextPainter can probably be made a Listenable now that it has a dispose method?
Hixie — Today at 2:44 PM
who updates the TextPainter?
LongCatIsLooong — Today at 2:45 PM
RenderEditable does so yeah technically it can implement the same logic to figure out whether the text layout will be dirtied
I think the same issue prevents us from caching things that depend on text layout outside of TextPainter since only TextPainter knows when to invalidate them
Hixie — Today at 2:47 PM
i think it's fine to recompute the rect each time we update the TextPainter even if that's a bit more often than necessary
the key is just to do it no more often than that :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: text inputEntering text in a text field or keyboard related problemsc: performanceRelates to speed or footprint issues (see "perf:" labels)frameworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions