lit-element icon indicating copy to clipboard operation
lit-element copied to clipboard

Add a way to know when rendering of an element, and ALL its sub-elements, is finished

Open mercmobily opened this issue 2 years ago • 2 comments

This is a meta-issue to replace closed ones. AS per sorvell's comment,

For efficiency, LitElement renders asynchronously. This makes it possible to batch property updates and integrate updating/rendering with a scheduler that can do chunking.

However, sometimes it's important to know when rendering has finished. While the updateComplete promise is provided for this purpose, for performance reasons it does not recurse into the element's render tree (the elements it creates). This makes it not useful for knowing when an element's complete subtree has fully rendered.

Steve's takle on the issue didn't make it into the main tree.

While proposing possible solution, Steve mentioned this:

Knowing when your subtree is fully rendered is sometimes needed when DOM needs to be measured. When possible, it's always best to wait until requestAnimationFrame to measure DOM. This works well with LitElement since, by default, rendering happens as microtask timing which is always fully completed before any tasks such as requestAnimationFrame or setTimeout. However, sometimes multiple reads from/writes to DOM are necessary to measure correctly. If these writes trigger additional updates/renders, then requestAnimationFrame is not sufficient.

One note I want to stress here is that

The platform answer to this problem is ResizeObserver. Forcing synchronous style/layout in order to measure elements breaks down at scale (...) Support for this is still pretty limited and polyfilling it is challenging.

Since the original tickets were submitted (#400 and #365), ResizeObserver has been polyfilled although I am not sure about performance.

@justinfagnani I hope this summary nails it.

mercmobily avatar Jul 23 '21 03:07 mercmobily

As noted in my comment, requestAnimationFrame can be used to wait until all elements have updated. This will only not be ideal if you need to make a series of changes that may need to depend on each other, each of which would have to wait for requestAnimationFrame. The reason this is not ideal is because there would then be likely undesirable screen paints before the chain of work is complete.

Does your use case fall into this category?

sorvell avatar Jul 29 '21 17:07 sorvell

I updated the original issue, I think I had missed something important. I think requestAnimationFrame will probably cover most cases. My main gripe with this are two things:

  • It's not exactly intuitive in its use.

I have done zero work with animation (I know right... I am a server guy at heart... really) and this function is really for:

The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. The method takes a callback as an argument to be invoked before the repaint. Note: Your callback routine must itself call requestAnimationFrame() again if you want to animate another frame at the next repaint. requestAnimationFrame() is 1 shot. You should call this method whenever you're ready to update your animation onscreen. This will request that your animation function be called before the browser performs the next repaint. The number of callbacks is usually 60 times per second, but will generally match the display refresh rate in most web browsers as per W3C recommendation

Which is not exactly overlapping with "Wait till all elements have done their updating"...

  • It's not 100% clear (to me anyway... I know, small mind) the actual use case when there are problems. For example you write "However, sometimes multiple reads from/writes to DOM are necessary to measure correctly. If these writes trigger additional updates/renders, then requestAnimationFrame is not sufficient." -- I am SURE this has happened to me, but it's difficult to predict and see; and frankly, I am not sure I totally understand 100% of what you mean (and with these problems 100% is the minimum necessary...). If you had endless time, I would beg for a practical example when this would happen. But I realise I am burdening you with yet another request...

Sorry if I wasn't overly helpful. I hope I am voicing other developer's questions as well.

mercmobily avatar Jul 31 '21 13:07 mercmobily

Closing as we have no plans to address this beyond what you can do now: await a task (as described above). If there is a concrete proposal here, it's a big enough feature that should be handled via an RFC.

sorvell avatar Sep 08 '22 21:09 sorvell