Skip to content

should keep script async attribute to false for block executing scripts #7

@kuitos

Description

@kuitos

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

const parentNode = targetNodes.get(node.parentNode!)!;

if (isSyncScript(clone)) {
  clone.async = false;
}

Your Environment

  • Chrome 119
  • MacOS 14.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions