WICG / canvas-place-element

Other
29 stars 3 forks source link

Buffering display list for automatic re-painting causes infinitely growing display list #15

Open khushalsagar opened 1 week ago

khushalsagar commented 1 week ago

In order to keep the element live, we need to keep buffering all commands which have been made to the 2D canvas. This allows re-composing the canvas buffer when the element's painting changes.

But this means you can have an infinitely growing display list which will tank perf in a way that might not be obvious to the author. There's a few ideas around it:

@smfr fyi.

smfr commented 1 week ago

None of these sound great. I really think that trying to shove a retained-mode type "live" element into an imperative-mode API is never going to work well.

Why not just go for the non-live version, with an event that tells the client that they need to repaint the element?

khushalsagar commented 1 week ago

There's 2 parts wrapped up into the live element version:

  1. The fact that the element repaints if anything changes. I can see how this wouldn't feel worth the complexity if the author can just repaint. But a big advantage is it allows the UA to retain optimizations like threaded scrolling.

  2. The browser can generate the hit testing data structures itself based on where the element is being painted. This can remove a decent bit of unnecessary state tracking/complexity for authors. Especially for cases where once the canvas is painted, all interaction is happening with the DOM and no change in canvas rendering is needed.

Maybe we can find the balance by only buffering one frame worth of commands? So every frame, the browser paints and stores the commands drawn to the canvas. If only placed elements are changing, the browser can redraw and also deal with hit testing automatically. But the next time script draws to the canvas, the buffer is cleared and script has to redraw the canvas completely.

Why not just go for the non-live version, with an event that tells the client that they need to repaint the element?

The non-live version should also be there. And I'd be ok if we started with that. I just don't want to close the door on the live version for the reasons above: better perf and developer ergonomics.