37

这个问题与哪些浏览器支持 <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);

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

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

4

4 回答 4

24

问题是s.async = true动态插入的脚本确实有用,或者这些脚本是否已经异步加载。答案是它们并非在所有浏览器中异步加载,如此所述(感谢 Markus Olsson 提供的链接)

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

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

(上面的链接确认 Gecko 1.9.2 支持异步,Firefox 3.6 使用的布局引擎)

于 2011-03-01T21:37:57.897 回答
20

规范(现在)规定插入解析器的script元素是异步的;该属性与非解析器插入的元素无关:asyncscript

第三个是指示元素是否将“强制异步”的标志。最初,script元素必须设置此标志。HTML 解析器和 XML 解析器在script它们插入的元素上取消设置它。此外,只要设置了“force-async”标志的脚本元素添加async内容属性,就必须取消设置元素的“ force-async ”标志。

当然,拥有asynccontent 属性确实意味着脚本将异步执行。规范语言似乎留下了强制同步执行脚本的机会(通过设置属性然后删除它),但在实践中这不起作用,并且可能只是规范中的一些模糊性。非解析器插入的script元素是异步的。

这种指定的行为是 IE 和 Chrome 一直在做的事情,Firefox 多年来一直在做,而当前的 Opera 也是如此(我不知道它何时改变了上面链接的答案中的旧行为)。

它很容易测试:

var script = document.createElement("script");
script.src = "script.js";
console.log("a");
document.body.appendChild(script);
console.log("b");

...与script.js存在

console.log("script loaded");

...将记录

一个
b
已加载脚本
于 2017-04-14T14:18:13.650 回答
3

有趣 - 我认为事实证明我的假设是错误的。

基于 jQuery 开发者论坛中的这个线程:

http://forum.jquery.com/topic/jquery-ajax-async-vs-html5-script-async

看起来该async属性已被发现对动态附加脚本有影响,至少在 Firefox 中(可能还有 Opera,尽管它还不支持该属性)。

论坛帖子还引用了 Google 的异步跟踪代码实现,尽管它似乎async在适当的上下文中使用了该属性,但实际上似乎语法错误。谷歌使用:

ga.async = true;

当显然这不起作用时;正确的方法是使用:

ga.async = 'async';

或者

ga.setAttribute('async', 'async');

因此,根据我目前的理解,并非所有浏览器在所有情况下都会在插入 DOM 后立即执行动态附加的脚本;Firefox(以及最终的 Opera)需要async设置该属性以确保始终发生这种情况。

有关 Firefox 在async此处实现的更多信息:

https://bugzilla.mozilla.org/show_bug.cgi?id=503481

于 2010-08-10T03:47:56.240 回答
1

I believe you're correct.

In Steve's own examples he does not set the async attribute before attaching the script tag to the head element.

My understanding of the async atttribute is that it's a way of signaling to the browser that you don't intend to manipulate the page by using document.write so that it can continue rendering instead of halting to load the script. See the documentation for the script element at mdc which contains a bit more on the document.write/async issues.

Note that with your technique you shouldn't use document.write anyway since you've got no way of knowing where in the page lifetime your script will be loaded.

于 2010-08-05T01:14:55.467 回答