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

"while a JavaScript event loop is running." is probably not intended #456

Open
jakearchibald opened this issue Nov 30, 2023 · 3 comments
Open
Assignees
Labels
Agenda+ Status: Consensus to write We have TAG consensus about the principle but someone needs to write it (see "To Write" project)

Comments

@jakearchibald
Copy link
Contributor

https://w3ctag.github.io/design-principles/#js-rtc

Don’t modify data accessed via JavaScript APIs while a JavaScript event loop is running.

An event loop is running from the creation of an agent, and it doesn't stop until the agent is destroyed. By this definition, data can never really update.

This should probably be reworded in terms of running scripts and callback invoking.

It might be worth calling out that new Date(), Date.now(), performance.now() are accepted breakages of this rule.

In fact, it's interesting to compare performance.now() to document.timeline.currentTime, as the former breaks run-to-completion, whereas the latter is stable for the whole frame (beyond a single callback).

@torgo torgo added this to the 2023-12-04-week milestone Dec 3, 2023
@torgo torgo added the Agenda+ label Dec 3, 2023
@torgo torgo added the Status: Consensus to write We have TAG consensus about the principle but someone needs to write it (see "To Write" project) label Dec 4, 2023
@torgo
Copy link
Member

torgo commented Dec 4, 2023

Hi Jake - thanks for sending us this! We discussed today and absolutely agree this needs to be fixed. Would it be possible for you to suggest a more concrete re-wording that we could consider?

@jakearchibald
Copy link
Contributor Author

Data can update synchronously from the result of developer action. Eg, node.remove() changes the DOM synchronously and is immediately observable.

However, things that are not the result of developer action, or are asynchronously delivered, should not happen in the middle of other JavaScript.

Meaning, during a while (true), you shouldn't expect things like:

  • The DOM to update as a result of the HTML parser loading network content
  • img.width to change as a result of loading image data from the network
  • Buttons of a gamepad to change state
  • scrollTop to change, even if scrolling can visually occur

These things aren't updated by the currently running script, so they shouldn't change during the currently running script. Instead, a task should be queued, or they should update as part of the render steps.

There are deliberate violations of this rule, such as Date.now() and performance.now(), which can observe changes in time, and things like the proposed isInputPending(), which read from task queues.

@torgo torgo modified the milestones: 2023-12-04-week, 2024-03-04-week Mar 3, 2024
@torgo torgo assigned matatk and unassigned cynthia Apr 3, 2024
@torgo
Copy link
Member

torgo commented Apr 3, 2024

We looked at this again today and we're going to work on making a PR in the coming weeks that adapt's the text Jake provided above.

@torgo torgo modified the milestones: 2024-04-01-week, 2024-06-03-week Jun 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Agenda+ Status: Consensus to write We have TAG consensus about the principle but someone needs to write it (see "To Write" project)
Projects
None yet
Development

No branches or pull requests

4 participants