New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Text layout without blocking the UI #41707
Comments
#23718 is more related to the general ability to measure a text widget, big or small, and make layout considerations based on that. For example, you may need to know if a single hz line can fit, and just hide it if it can't. |
That is already possible, but only practical in cases where the text is reasonable short. |
I see, thanks! |
Do we know if these cases could be handled if the text measuring was done in parallel? I was wondering if maybe what we could do is when we build a RenderParagraph, we have it immediately inform the engine about the text it cares about, so that the engine can warm its caches for that text, so that by the time we come to actually measuring the text, it can respond much quicker than now. |
I'm not sure what part you mean when asking in parallel. If we did the whole text layout operation on another thread while we kept moving along, I think that's basically the API this issue is asking for. If we, alternatively, somehow parallelized text layout so that multiple threads could figure out how to lay out a paragraph, that might help too. Are you suggesting that we implicitly call |
I'm suggesting that The "parallel" part applies in the sense that multiple such RichText/RenderParagraph/TextPainter groups would all call this new API during the widget build phase, before layout, such that all these text node would be warming up simultaneously in the engine. We can't call |
I don't think anyone has profiled which parts of this take a long time. However, this bug was inspired more by dealing with longer strings of text where the actual layout is the non-fixed cost (as opposed to loading font attributes). This would have disadvantages where you may not know the full size of e.g. a sliver you want to layout, but I suspect in a lot of cases developers do know (or could make reasonable decisions) about what size to lay text out ahead of time. |
Almost all RenderParagraph nodes have no idea what size they'll be until layout time, as far as I can tell (at which time they need the answer synchronously). |
I am working on some custom textviewer and I faced #92173 issue. I also piled up all similar issues in this comment. My point here is layout call is expensive at present. So if layout is done in seperate isolate or async and if it is expensive just like at present then also we will have to wait for layout details till layout call is complete. This would not be much beneficial in cases like #55722, #58478, #92173. My suggestion here is workaround should also be done to improve the performance of layout call. |
@Hixie - we could create a widet/RO that knows how to deal with async text layout, similar to how we deal with async image loading today. Developers with application domain knowledge could say "start at this size, which should be close", and text would eventually come in at the right size. I'm not sure if it's possible to have any heuristics to guess something close to the right size, but maybe we could do something close to accurate with the length of the string. |
Imagine, for example, a list of small strings, each of which takes ~1ms to lay out and each of which will be shown with an ellipsis if they are too long to fit on onel ine. As soon as you have more than 8 of these strings you're over budget on text layout alone. Async text layout would help a lot here, because you could just have your list tiles render faster and eventually put the strings in as they become available, rather than losing 1 or more frames worth of budget waiting for an answer on initial layout. |
#94419 contains an actual example that renders 9 list tiles with 3 RenderParagraphs each. On average on a low-end device, each RenderParagraph takes 1.0ms to lay out, which means 27ms alone are spend laying out text in this rather simple screen. |
The idea of precomputing some text metrics asynchronously and kicking that off right when the RenderObject is configured (way ahead of the layout phase) sounds interesting. This would be similar to Android's |
//cc @Rusino |
I've spun out the 2-step text layout idea into its own issue with some experimental data showing that in theory this could help with improving build/layout times: #96235 |
There are a number of bugs that I've seen that boil down to this: if you have a large chunk of text, laying it out may be expensive enough where it blocks the UI for an unacceptable amount of time. One work around for this is to try to break up your text into smaller chunks, which works if you already have natural breaks (e.g. many small paragraphs laid out individually instead of all at once), but doesn't work as well if you just have a really long paragraph you want to layout and you don't know where the line breaks will fall. This may be a problem for, e.g. a reader for an academic journal that just has long paragraphs, or perhaps in some other languages where longer paragraphs may be more common.
It is not currently possible to layout text in a separate isolate, as all dart:ui methods must run in the main isolate. We should explore either making it possible to run in another isolate, or creating some async text layout methods.
Here are some example issues:
#23718
#30604
#41536 (not as strongly related but may be helped by such an API)
/cc @GaryQian @jason-simmons
The text was updated successfully, but these errors were encountered: