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

Define timing of script execution in relation to DOM mutations better #1127

Open
annevk opened this issue Apr 26, 2016 · 5 comments
Open

Define timing of script execution in relation to DOM mutations better #1127

annevk opened this issue Apr 26, 2016 · 5 comments

Comments

@annevk
Copy link
Member

annevk commented Apr 26, 2016

See http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=4098.

I think this is most clearly demonstrated when inserting a DocumentFragment node, but maybe there are similar scenarios I don't know about. Basically, the elements are inserted first, one by one, and then executed, one by one. This requires looping over the inserted elements twice. Probably once with a "disable script flag" and once without.

@smaug---- might have some ideas around designing this in a different way.

This came out of review in #1100 which indicated that currently this is not really defined properly at all.

@annevk
Copy link
Member Author

annevk commented Feb 19, 2018

This seems hard to fix. We cannot just run "insertion steps" twice since there'd be too many side effects for other elements. The simplest thing I can think of is keeping track of inserted HTML/SVG script elements and then invoking their insertion algorithm at the end of https://dom.spec.whatwg.org/#concept-node-insert.

@domenic
Copy link
Member

domenic commented Feb 19, 2018

Might it be worth finding out how implementations work here? @nyaxt or @hiroshige-g could probably help from the Chrome side.

@annevk
Copy link
Member Author

annevk commented Feb 19, 2018

I looked at Firefox's code in whatwg/dom#575 and it seems any notifications happen after all nodes are inserted, which seems reasonable. I haven't quite investigated if any scripts executing at that point can mess things up though.

(I also found that Safari is alone in reporting different numbers for the test, but hopefully they're willing to align.)

@rniwa
Copy link
Collaborator

rniwa commented Feb 19, 2018

In WebKit, we create a queue of "tasks" (e.g. firing events, adding a new stylesheet) while inserting nodes, and then execute those items in the queued order. There is an interesting race condition here in the case where those inserted nodes are subsequently removed in one of the "tasks". I think we'd just go ahead and execute all the queued "tasks". I wonder what Gecko & Edge do in those cases.

@smaug----
Copy link
Collaborator

In WebKit, we create a queue of "tasks" (e.g. firing events, adding a new stylesheet) while inserting nodes

FWIW, that sounds very similar to Gecko. We call these tasks ScriptRunners.

annevk pushed a commit to whatwg/dom that referenced this issue Jun 5, 2024
For any given insert operation, these steps run for each inserted node synchronously after all node insertions are complete. This closes #732.

The goal here is to separate the following:

1. Script-observable but not-script-executing insertion side effects
    - This includes synchronously applying styles to the document, etc...
2. Script-executing insertion side effects
    - This includes creating an iframe's document and synchronously firing its load event

For any given call to insert, the above model allows us to keep all of (1) running synchronously after each node's insertion (as part of its insertion steps), while pushing all script-executing (or DOM tree-modifying or frame tree-modifying etc.) side effects to the new set of post-connection steps, which run synchronously during insertion, but _after all_ nodes finish their insertion.

This essentially makes insertions "atomic" from the perspective of script, since script will not run until a given batch of DOM insertions are complete. This two-stage approach aligns the spec with a model most similar to Blink & Gecko's implementation, and fixes #808. This PR also helps out with whatwg/html#1127 and #575 (per #732 (comment)).

To accomplish, this we audited all insertion side effects on the web platform in https://docs.google.com/document/d/1Fu_pgSBziVIBG4MLjorpfkLTpPD6-XI3dTVrx4CZoqY/edit#heading=h.q06t2gg4vpw, and catalogued whether they have script-observable side-effects, whether they invoke script, whether we have tests for them, and how each implementation handles them. This gave us a list of present "insertion steps" that should move to the "post-connection steps", because they invoke script and therefore prevent insertions from being "atomic". This PR is powerless without counterpart changes to HTML, which will actually _use_ the post-connection steps for all current insertion steps that invoke script or modify the frame tree. The follow-up HTML work is tracked here:

- whatwg/html#10188
- whatwg/html#10241
vinhill pushed a commit to vinhill/dom that referenced this issue Jun 20, 2024
For any given insert operation, these steps run for each inserted node synchronously after all node insertions are complete. This closes whatwg#732.

The goal here is to separate the following:

1. Script-observable but not-script-executing insertion side effects
    - This includes synchronously applying styles to the document, etc...
2. Script-executing insertion side effects
    - This includes creating an iframe's document and synchronously firing its load event

For any given call to insert, the above model allows us to keep all of (1) running synchronously after each node's insertion (as part of its insertion steps), while pushing all script-executing (or DOM tree-modifying or frame tree-modifying etc.) side effects to the new set of post-connection steps, which run synchronously during insertion, but _after all_ nodes finish their insertion.

This essentially makes insertions "atomic" from the perspective of script, since script will not run until a given batch of DOM insertions are complete. This two-stage approach aligns the spec with a model most similar to Blink & Gecko's implementation, and fixes whatwg#808. This PR also helps out with whatwg/html#1127 and whatwg#575 (per whatwg#732 (comment)).

To accomplish, this we audited all insertion side effects on the web platform in https://docs.google.com/document/d/1Fu_pgSBziVIBG4MLjorpfkLTpPD6-XI3dTVrx4CZoqY/edit#heading=h.q06t2gg4vpw, and catalogued whether they have script-observable side-effects, whether they invoke script, whether we have tests for them, and how each implementation handles them. This gave us a list of present "insertion steps" that should move to the "post-connection steps", because they invoke script and therefore prevent insertions from being "atomic". This PR is powerless without counterpart changes to HTML, which will actually _use_ the post-connection steps for all current insertion steps that invoke script or modify the frame tree. The follow-up HTML work is tracked here:

- whatwg/html#10188
- whatwg/html#10241
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

5 participants
@rniwa @domenic @annevk @smaug---- and others