-
Notifications
You must be signed in to change notification settings - Fork 28.6k
Strategies for static content rendering performance #115257
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
Comments
@chinmaygarde @jason-simmons - You probably know the answer to this. |
Hi @matthew-carroll, I'm curious about how the display list diagnosis was reached. If there was already a discussion going on another github issue or discord thread, would you mind linking that here? cc @flar |
@matthew-carroll we need a code example to diagnose this. |
Specifically on the code example, it'd be really good to have something that shows the bad behavior with the repaint boundary you're seeing. If that's a bug in the framework or engine we'd like to fix it. On the broader question about performance it'd help to see some tracing and understand what's slow. It's hard to answer in the abstract. M
8000
aybe a strategy that preserves picture layers (like what flutter_svg currently does) would help. Maybe you need an API that lets you render text without using the whole of the paragraph machinery on each frame. Maybe you need to do something like use |
Here's a thread dealing with the long-running display list transfer: That ticket focuses on the fact that it takes a long time to push the display list. It would obviously be a big help to find a way to eliminate the time for all display list pushes. This ticket is looking more at mitigation strategies to eliminate all unnecessary recreations of that display list.
I'll need to figure out how to share useful snippets of code. I'll chat with my client and see what we can do. |
I'm not sure we need the entire original application, but the code sample that were used to make those videos - the ones that showed the transform bugs - would help us diagnose the problem you are getting when you add the RepaintBoundaries. |
Preserving the display list won't help you here, since what's actually expensive is rasterizing all the text in the displaylist. It sounds like what you're looking for is It would still be nice to know more about the bug in the video around the repaint boundaries. |
I think I've confirmed that the layout issue was my fault. I was doing something that wasn't quite right in terms of canvas vs layer transforms. I think I've fixed it. I still plan to bring more material to this ticket, as requested. I need to reach an appropriate stopping point with my current work so that I can figure out what to extract and post here. |
I just saw this question within the original description. When recording to a Canvas, say in a CustomPaint or any RenderObject that executes calls on a ui.Canvas object, it is recording local coordinates. There is no initial transform in the ui.Recorder or ui.Canvas. The transforms in parent Widgets/RenderObjects are expressed by enclosing Transform objects and the recordings within a given Canvas are played back relative to those transforms. If you have a RepaintBoundary around the generation of that display list, then the contents of that RepaintBoundary are severed from any connection with the surrounding painting and that display list is not regenerated unless a Widget underneath the RepaintBoundary widget indicates some need to repaint (such as an animation). It couldn't contain global coordinates otherwise it couldn't do its job of avoiding the rebuilding of the display list (or in some cases display lists) that its children generate. |
Update: We've done a lot of optimizing for document rendering. Layout When we run layout, we're caching Painting The best answer here would be for Flutter to expose some of the lower level text painting abilities in Skia. We'd like to be able to say something like Currently, we've worked around the Rasterization Shader Compilation Summary We'd love to see the ability to creating We don't know what to do about the raster process. We can't explain why it's taking so long and we're not sure what we can do about it. |
Some related issues:
|
Out of curiosity, how large is the text layout? Does it cover visible area, or entire document? |
At the moment, we're rendering an entire page at a time, regardless of visible area. That said, such a thing needs to be possible, anyway, because if the user zooms out, then the user is going to see the entire page. So aggressive culling might be a nice late-stage optimization, but lagging when the full page is visible isn't really acceptable. |
I might be a bit confused with terminology. What exactly is a page? Text layouts usually works with documents and paragraphs. My question is, whether the entire document is laid out, or just the paragraphs currently being visible. The problem I see here is that no matter how well you optimise the layout, if you keep laying out the entire document you are bound to reach the size where you just can't do that at interactive speeds. For example TextKit 1 used to layout entire document by default and partial layout was an opt-in. In TextKit 2 partial layout is the default and laying-out anything outside visible viewport need to be manually requested. Considering partial layout a late-state optimisation seems a bit strange to me. |
To be clear about terminology:
While rendering multiple pages in a document at the same time will certainly exacerbate performance issues, this ticket refers to issues that are faced when rendering even one page at at time. My point above is that we shouldn't have any issue rendering a single page, at a typical page size. We can open any popular document viewing or editing application and we can view a single page without issue. That page isn't culling any content, because all of its content is visible. |
I'm rendering document pages, which seems to be very performance intensive. I'm not entirely sure why. The volume of content in the document pages isn't dramatic. Nonetheless, the time to push the display list to the engine takes many frames.
Putting aside the time to push the initial display list, is there a way to cache a document page's display list in the engine, such that the page can be scaled up/down, without sending over another display list? The page content doesn't change after the initial render, only the ancestor transformations, so I would hope that there's a way to avoid any additional
RenderObject
work, but I haven't found such a path.I tried wrapping each page with a
RepaintBoundary
, but this seems to yield very strange behavior when scaling up/down. Does the display list within aRepaintBoundary
apply ancestor transformations up front, and then retain global coordinates? Or does the display list within aRepaintBoundary
retain local coordinates and then play those on top of ancestor transformations in the engine? If the former, that might explain the weird behavior that I'm seeing.Here are a couple videos that show the
RepaintBoundary
problem. In this first video, I have a series of "pages" that I can scroll and scale. The pages changes size as expected, they continue to meet exactly where they should, and the circle in the center grows and shrinks as expected.pages_without-repaint-boundary.mp4
In this next video, I took the exact same code and added a
RepaintBoundary
around aCustomPaint
, which paints the circle at the center of each page. Here's what happens now.pages_with-repaint-boundary.mp4
These pages are laid out in a custom
RenderObject
, so it's possible that I'm screwing something up, but in the absence of aRepaintBoundary
, the children appear with the offset and scale that they should.So that's a problem that's actively preventing me from using a
RepaintBoundary
, but I'm also wondering if there are any other caching strategies that would allow content transformation without regenerating the display list for each page?The text was updated successfully, but these errors were encountered: