javascript 如果将脚本动态添加到 DOM,“async”属性/属性是否有用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3408805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is the "async" attribute/property useful if a script is dynamically added to the DOM?
提问by Bungle
This question is sort of a tangent to Which browsers support <script async="async" />?.
这个问题与哪些浏览器支持 <script async="async" />?.
I've seen a few scripts lately that do something like this:
我最近看到一些脚本做这样的事情:
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);
This is a common way to add a script to the DOM dynamically, which, IIRC from Steve Souders's book "Even Faster Web Sites," prompts all modern browsers to load the script asynchronously (i.e., not blocking page rendering or downloading of subsequent assets).
这是向 DOM 动态添加脚本的常用方法,根据 Steve Souders 的书“甚至更快的网站”中的IIRC,它提示所有现代浏览器异步加载脚本(即,不阻止页面渲染或下载后续资产) .
If I'm correct in that, does the s.async = truestatement have any use? Wouldn't it be redundant, even for the browser(s) that support that property, since dynamically appended a script should already trigger asynchronous downloading?
如果我的s.async = true说法是正确的,那么该声明是否有任何用处?即使对于支持该属性的浏览器,它也不是多余的,因为动态附加的脚本应该已经触发了异步下载?
采纳答案by T.J. Crowder
The specification(now) dictates that a scriptelement that isn'tparser-inserted is async; the asyncproperty is irrelevant to non-parser-inserted scriptelements:
的规范(现在)决定了一个script该元素并不解析器插入是异步; 该async属性与非解析器插入的script元素无关:
The third is a flag indicating whether the element will "force-async". Initially,
scriptelements must have this flag set. It is unset by the HTML parser and the XML parser onscriptelements they insert. In addition, whenever a script element whose "force-async" flag is set has aasynccontent attribute added, the element's "force-async" flag must be unset.
第三个是指示元素是否将“强制异步”的标志。最初,
script元素必须设置此标志。HTML 解析器和 XML 解析器对script它们插入的元素取消设置。此外,每当设置了“ force-async”标志的脚本元素async添加了内容属性时,必须取消设置该元素的“ force-async”标志。
Having the asynccontent attribute does, of course, mean the script would be executed asynchronously. The spec language seemsto leave an opportunity to force synchronous execution of the script (by setting the attribute and then removing it), but in practice that does not work and is probably just a bit of vagueness in the spec. Non-parser-inserted scriptelements are async.
async当然,拥有content 属性意味着脚本将异步执行。规范语言似乎留下了强制同步执行脚本的机会(通过设置属性然后删除它),但实际上这不起作用,并且规范中可能只是有点模糊。非解析器插入的script元素是异步的。
This specified behavior is what IE and Chrome have always done, Firefox has done for years, and current Opera also does (I have no idea when it changed from the old behavior in the answer linked above).
这种指定的行为是 IE 和 Chrome 一直在做的,Firefox 多年来一直在做,而当前的 Opera 也是如此(我不知道它何时从上面链接的答案中的旧行为改变了)。
It's easily tested:
它很容易测试:
var script = document.createElement("script");
script.src = "script.js";
console.log("a");
document.body.appendChild(script);
console.log("b");
...with script.jsbeing
...与script.js存在
console.log("script loaded");
...will log
...将记录
a b script loaded
回答by Tim Goodman
The question is does s.async = truehave a use for dynamically inserted scripts, or are these loaded asynchronously already. The answer is they aren'tloaded asynchronously in all browsers, as explained here(thanks to Markus Olsson for the link)
问题是s.async = true动态插入的脚本确实有用,或者这些脚本是否已经异步加载了。答案是,他们没有在所有的浏览器异步加载,如解释在这里(感谢马库斯·奥尔森的链接)
script-inserted scripts execute asynchronously in IE and WebKit, but synchronously in Opera and pre-4.0 Firefox. In Firefox 4.0, the async DOM property defaults to true for script-created scripts, so the default behavior matches the behavior of IE and WebKit.
插入脚本的脚本在 IE 和 WebKit 中异步执行,但在 Opera 和 4.0 之前的 Firefox 中同步执行。在 Firefox 4.0 中,异步 DOM 属性对于脚本创建的脚本默认为 true,因此默认行为与 IE 和 WebKit 的行为相匹配。
In browsers that support asyncbut don't already default to asynchronous loading (for example, Firefox 3.6), async = truemakes a difference.
在支持async但尚未默认异步加载的浏览器(例如,Firefox 3.6)中,情况async = true有所不同。
(The above link confirms that async is supported in Gecko 1.9.2, the layout engine used by Firefox 3.6)
(以上链接确认了 Firefox 3.6 使用的布局引擎 Gecko 1.9.2 支持 async)
回答by Bungle
Interesting - I think it turns out that I was wrong in my assumptions.
有趣 - 我认为事实证明我的假设是错误的。
Based on this thread in the jQuery developers' forum:
基于 jQuery 开发者论坛中的这个线程:
http://forum.jquery.com/topic/jquery-ajax-async-vs-html5-script-async
http://forum.jquery.com/topic/jquery-ajax-async-vs-html5-script-async
it looks like the asyncproperty has been discovered to have an effect on dynamically-appended scripts, at least in Firefox (and potentially Opera, though it doesn't yet support the property).
看起来该async属性已被发现对动态附加的脚本有影响,至少在 Firefox 中(可能还有 Opera,尽管它尚不支持该属性)。
The forum thread also cites Google's asynchronous tracking code implementation, which, although it appears to make use of the asyncproperty in the appropriate context, actually appears to get the syntax wrong. Google uses:
该论坛帖子还引用了 Google 的异步跟踪代码实现,尽管它似乎async在适当的上下文中使用了该属性,但实际上似乎语法错误。谷歌使用:
ga.async = true;
when apparently that doesn't work; the proper method would be to use either:
当这显然不起作用时;正确的方法是使用:
ga.async = 'async';
or
或者
ga.setAttribute('async', 'async');
So, based on my current understanding, not all browsers will actually execute dynamically-appended scripts immediately upon their insertion into the DOM in all cases; Firefox (and eventually Opera) will need the asyncproperty to be set to ensure that this always happens.
因此,根据我目前的理解,并非所有浏览器在所有情况下都会在插入 DOM 后立即执行动态附加脚本;Firefox(以及最终的 Opera)需要async设置该属性以确保这总是发生。
More info on Firefox's implementation of asynchere:
有关 Firefox 实现的更多信息async:
回答by Markus Olsson
I believe you're correct.
我相信你是对的。
In Steve's own exampleshe does not set the async attribute before attaching the script tag to the head element.
在史蒂夫自己的例子中,他没有在将脚本标签附加到 head 元素之前设置 async 属性。
My understanding of the async atttributeis 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 mdcwhich contains a bit more on the document.write/async issues.
我对async 属性的理解是,它是一种向浏览器发出信号的方式,表明您不打算通过使用 document.write 来操作页面,以便它可以继续呈现而不是停止加载脚本。请参阅mdc 上的script 元素的文档,其中包含有关 document.write/async 问题的更多信息。
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.
请注意,使用您的技术,您无论如何都不应该使用 document.write,因为您无法知道您的脚本将在页面生命周期中的何处加载。

