flutter-code-editor icon indicating copy to clipboard operation
flutter-code-editor copied to clipboard

Improve the key-to-display response time

Open alexeyinkin opened this issue 1 year ago • 4 comments

alexeyinkin avatar Sep 23 '22 10:09 alexeyinkin

Flutter code editor performance research

Source data

web-renderer: canvaskit build mode: profile (release mode misuse here because compiler hide methods names, so we can’t recognize them in devtools) language: python theme: monokai-sublime code: copy-pasted several times MinimalWordCount example. (2058 rows total) testing actions: change cursor position and add symbol

Changing cursor position took about 545 ms for 2 largest events. Call stack of both of them mostly belongs to flutter source code, so we can’t handle it. Image

Adding symbol took about 847 ms for 2 largest events. We can work with about 10% of this time, another one flutter uses for layouting.
Image

What already has been tried:

  1. Tried to find custom textfield for our requirements
  2. Tried to change current textfield properties for better performance

Possible ways to improve

  1. Splitting one big textfield on textfields list
  2. Set to textfield just visible text with extra viewport at top and bottom for smooth scrolling

Malarg avatar Sep 28 '22 05:09 Malarg

How to use DevTools:

https://user-images.githubusercontent.com/17158960/192697669-07d934cf-fe2f-4b47-b3e3-74b6ec042885.mov

Malarg avatar Sep 28 '22 05:09 Malarg

Highlighted is the current overhead of the comment parser, the foldable block parser, and other add-ons of ours. Hence we don't plan to optimize them. Improvements must be done in the Flutter part if we want them.

image

Keeping this open.

alexeyinkin avatar Oct 01 '22 05:10 alexeyinkin

  • Seems like I duplicated this issue here #170

Little summary from the "discussion" from there. TextField uses TextPainter inside, which takes a long time to layout if the text is huge. As I found, there is no way to affect to this.

TextPainter.layout() -> expensive TextPainter.paint() -> cheap (can only be called after layout)

If we try to use CustomPaint with caching TextPainters to make efficient use of them, it still scales quickly enough to become laggy at 700 lines of code.

Using ListView.builder to display only visible lines doesn't work for some reason. Even though ListView.builder documentation says that it builds the widgets on demand, that is not what I actually experienced when testing it. It was even more laggy than CustomPaint approach.

Finally, the solution that is similar to ListView.builder -> CustomScrollView with slivers. This actually builds only those widgets, that are currently visible on the ViewPort. I believe this will allow us to reach maximum performance, as well as a whole bunch of new opportunities:

  • Drawing indentation indicators
  • Drawing errors indicators on the text position
  • Drawing anything along with the text. (like folded block indicators, helper comments like flutter widgets etc.)
  • Expose API for painting on the TextField so that users can do whatever they want on it.

Although, I also like the solution proposed by @Malarg, to split the TextField into many TextFields. That will definitely work. But that implementation is also hard, while not providing other benefits apart from performance.

yescorp avatar Feb 17 '23 13:02 yescorp