RESOLVED FIXED 235322
Adding iframe flushes microtasks synchronously with dirty stack
https://bugs.webkit.org/show_bug.cgi?id=235322
Summary Adding iframe flushes microtasks synchronously with dirty stack
Dan Abramov
Reported 2022-01-18 10:23:06 PST
Created attachment 449401 [details] repro Microtasks are supposed to run on a clean stack. However, Safari flushes microtasks synchronously if you append an iframe to the page. This breaks expectations for libraries like React/Preact, and possibly others: - https://github.com/facebook/react/issues/22459 - https://github.com/preactjs/preact/issues/2814 Here is a simple repro: ``` queueMicrotask(() => { console.log("--- in microtask ---"); }); console.log("will add iframe"); const iframe = document.createElement("iframe"); iframe.src = "localhost"; document.body.appendChild(iframe); console.log("did add iframe"); ``` You need to run it with http server to repro. It doesn't repro from file://. Expected output: ``` will add iframe did add iframe --- in microtask --- ``` Safari output: ``` will add iframe --- in microtask --- did add iframe ```
Attachments
repro (400 bytes, text/html)
2022-01-18 10:23 PST, Dan Abramov
no flags
WIP (939 bytes, patch)
2022-06-28 23:53 PDT, Ryosuke Niwa
no flags
WIP2 (2.92 KB, patch)
2022-06-29 01:13 PDT, Ryosuke Niwa
no flags
Patch (8.15 KB, patch)
2022-06-29 11:19 PDT, Ryosuke Niwa
no flags
Jason Miller
Comment 1 2022-01-18 13:20:46 PST
I spent a bit of time checking various forms of this issue: https://jsfiddle.net/developit/u6xztc93/ I was able to narrow the issue down: - microtasks are only flushed in the realm of the frame's ownerDocument. - flush is *not* triggered for sandboxed iframes. - flush *is* triggered for cross-origin iframes. (presumably because it's not known to be cross-origin at append time) - flush *is* triggered for iframes within <svg><foreignObject>. - other elements (svg/img/video/object/embed) do not trigger flush.
Radar WebKit Bug Importer
Comment 2 2022-01-25 10:23:43 PST
Ryosuke Niwa
Comment 3 2022-06-28 22:50:38 PDT
I don't think this is a regression. The issue really stems from the fact we're still firing DOMContentLoaded and load events synchronously in Document::finishedParsing(). Since this code gets to run when inserting an iframe as a part of creating the initial empty document, we end up performing the microtask checkpoint. Making DOMContentLoaded and load events fully asynchronous is a major undertaking but we can workaround this specific issue by detecting that's what's about to happen and avoid performing microtask checkpoint.
Ryosuke Niwa
Comment 4 2022-06-28 23:53:55 PDT
Created attachment 460532 [details] WIP We can detect the case where we're creating initial empty document like this. But this doesn't work when we're implicitly navigating to about:blank (blank iframe).
Ryosuke Niwa
Comment 5 2022-06-29 01:11:38 PDT
Yikes. This must be a regression from https://trac.webkit.org/r234944.
Ryosuke Niwa
Comment 6 2022-06-29 01:13:19 PDT
Ryosuke Niwa
Comment 7 2022-06-29 11:07:49 PDT
Ryosuke Niwa
Comment 8 2022-06-29 11:19:13 PDT
Ryosuke Niwa
Comment 9 2022-06-29 11:23:39 PDT
EWS
Comment 10 2022-06-30 14:40:46 PDT
Committed 252015@main (ea74655e102a): <https://commits.webkit.org/252015@main> Reviewed commits have been landed. Closing PR #1909 and removing active labels.
Ryosuke Niwa
Comment 11 2022-08-05 17:40:22 PDT
*** Bug 243488 has been marked as a duplicate of this bug. ***
Matt d'Entremont
Comment 12 2023-01-24 09:47:57 PST
The commit for the fix doesn't seem to be part of any Safari-specific git tags, but it is in Safari branches safari-7614.1.20-branch all the way up to safari-7615.1.9-branch. I see it mentioned in the Safari tech preview 150 release notes, but not in any of the mainline release notes. Is this released to the general public yet?
Ryosuke Niwa
Comment 13 2023-01-24 11:40:43 PST
(In reply to Matt d'Entremont from comment #12) > The commit for the fix doesn't seem to be part of any Safari-specific git > tags, but it is in Safari branches safari-7614.1.20-branch all the way up to > safari-7615.1.9-branch. > > I see it mentioned in the Safari tech preview 150 release notes, but not in > any of the mainline release notes. > > Is this released to the general public yet? It should be in Safari 16.
Note You need to log in before you can comment on or make changes to this bug.