如果脚本动态添加到DOM,"async"属性/属性是否有用?

Bun*_*gle 32 javascript asynchronous pageload page-load-time

这个问题与哪些浏览器支持<script async ="async"/>相关?.

我最近看过几个脚本做的事情是这样的:

var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://www.example.com/script.js';
document.getElementsByTagName('head')[0].appendChild(s);
Run Code Online (Sandbox Code Playgroud)

这是向DOM动态添加脚本的常用方法,Steve Souders的书" Even Faster Web Sites "中的IIRC 提示所有现代浏览器异步加载脚本(即不阻止页面呈现或下载后续资产) .

如果我是正确的,该s.async = true声明是否有用?即使对于支持该属性的浏览器,它也不是多余的,因为动态附加脚本应该已经触发异步下载吗?

Tim*_*man 21

问题是s.async = true对动态插入的脚本有用,还是已经异步加载.答案是,他们没有在所有的浏览器异步加载,如解释在这里(感谢马库斯·奥尔森的链接)

脚本插入的脚本在IE和WebKit中异步执行,但在Opera和4.0之前的Firefox中同步执行.在Firefox 4.0中,对于脚本创建的脚本,async DOM属性默认为true,因此默认行为与IE和WebKit的行为相匹配.

在支持async但尚未默认为异步加载的浏览器(例如,Firefox 3.6)中,async = true有所作为.

(上面的链接确认了Gecko 1.9.2支持async,这是Firefox 3.6使用的布局引擎)


T.J*_*der 15

截至撰写本文时,接受答案已过时.该规范现在决定了一个script该元素并不解析器插入是异步; 该async属性与非解析器插入的script元素无关:

第三个是一个标志,指示元素是否" 强制 - 异步 ".最初,script元素必须设置此标志.script它们插入的元素上的HTML解析器和XML解析器没有设置它.此外,每当设置了" force-async "标志的脚本元素async添加了content属性时,必须取消设置元素的" force-async "标志.

async当然,拥有content属性意味着脚本将异步执行.规范语言似乎有机会强制同步执行脚本(通过设置属性然后删除它),但实际上这不起作用,可能只是在规范中有点模糊.非解析器插入的script元素是异步的.

这个指定的行为是IE和Chrome一直以来所做的,Firefox已经做了多年,而且当前Opera也做了(我不知道它何时从上面链接的答案中的旧行为改变).

它很容易测试:

var script = document.createElement("script");
script.src = "script.js";
console.log("a");
document.body.appendChild(script);
console.log("b");
Run Code Online (Sandbox Code Playgroud)

...与script.js

console.log("script loaded");
Run Code Online (Sandbox Code Playgroud)

...会记录

a
b
script loaded