-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Version: 1.0.3
Details
I found that non-async scripts marked with defer will become async after insertion, which causes the defer scripts not to be executed in document order. There is no problem with non-defer synchronous scripts because we have a blocking flow that waits for the previous script to finish before loading the next one.
I did some digging and found that this is because scripts written through a documentFragment will all become async true, and the same issue exists with document.importNode.
Here is example code to explain the issue:
const doc = document.implementation.createHTMLDocument('');
doc.write('<!DOCTYPE html><body><template>');
const root = (doc.body.firstChild).content;
const walker = doc.createTreeWalker(root);
doc.write('<script src="./a.js"></script>');
console.log(walker.root.children[0].async); // true
const script = document.createElement('script');
script.async = false;
const clone = document.importNode(script);
console.log(clone.async); // true
Expected Behavior
defer script without async attribute on html should execute in the order in which they appear in the document.
Actual Behavior
defer script without async attribute on html not executed in order
Possible Fix
set script element async attribute correctly before it been append to target document
Line 121 in 020d50b
const parentNode = targetNodes.get(node.parentNode!)!; |
if (isSyncScript(clone)) {
clone.async = false;
}
Your Environment
- Chrome 119
- MacOS 14.0