Skip to content
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

[RRFC] Reduce the need to understand and mitigate Lit's asynchronous update model. #27

Open
sorvell opened this issue Sep 18, 2023 · 1 comment

Comments

@sorvell
Copy link
Member

sorvell commented Sep 18, 2023

  • [X ] I searched for an existing RRFC which might be relevant to my RRFC

Motivation

Standard platform behavior for elements is that they update synchronously after being mutated. If an element's textContent is set in such a way that its height would change, checking offsetHeight on the element is synchronously valid.

For efficiency, Lit elements update asynchronously and do not have this guarantee. Instead, users must await element.updateComplete to ensure any pending work is completed.

This is often not a problem because all updates are complete at task timing and before painting via await new Promise(requestAnimationFrame). However, it comes up in some cases and can be hard to deal with. In addition, if updateComplete is awaited, this does not reflect the status of any nested Lit elements unless users explicitly implement the promise to do so.

To mitigate this behavior, a mixin can be provided which does 2 things:

  1. updating the element synchronously makes the element's entire shadow subtree update.
  2. any element properties will ensure any pending update is synchronously completed before returning their current value.

How

Here is a prototype implementing the two proposed behaviors via a ReactiveManager mixin.

  1. it tracks child elements updated as a result of an element itself updating, and ensure they also update before the element's update is finished.
  2. it customizes reactive property accessors so that gets call performUpdate before returning their value, being careful not to do so during actual rendering.
@sorvell sorvell changed the title [RRFC] Reduce users' need to understand and mitigate Lit's asynchronous update model. [RRFC] Reduce the need to understand and mitigate Lit's asynchronous update model. Sep 18, 2023
@filimon-danopoulos-stratsys

In addition, if updateComplete is awaited, this does not reflect the status of any nested Lit elements unless users explicitly implement the promise to do so.

IMO this is the big issue that need addressing in one way or another. There are two issues that I have run into that makes implementing getUpdateComplete error prone.

  1. When getUpdateComplete is implemented it is very easy to forget updating it if render is updated. This increases mental load when authoring components as every component added to render requires a scan of getUpdateComplete. Forgetting to properly update getUpdateComplete can (and has) lead to obscure timing bugs.
  2. Writing getUpdateComplete for components that have conditional children duplicates the selection logic. Sometimes it is fairly easy to extract into a common function, other times this can really muddle the implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants