是“异步”吗?如果脚本动态添加到 DOM,属性/属性有用吗?
这个问题有点与 哪些浏览器支持
我最近看到一些脚本做了这样的事情:
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 的常见方法,IIRC 来自 Steve Souders 的书“更快的网站" 提示所有现代浏览器异步加载脚本(即,不阻止页面呈现或后续资源的下载)。
如果我是正确的,那么 s.async = true
语句有任何用处吗?即使对于支持该属性的浏览器来说,这不是多余的吗?因为动态附加的脚本应该已经触发异步下载了?
This question is sort of a tangent to Which browsers support <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).
If I'm correct in that, does the s.async = true
statement 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
问题是 s.async = true 是否有用于动态插入的脚本,或者这些脚本是否已经异步加载。答案是它们不是在所有浏览器中异步加载,正如此处(感谢 Markus Olsson 提供的链接)
在支持
async
但尚未默认异步加载的浏览器(例如 Firefox 3.6)中,async = true
会有所不同。(上面的链接确认了 Gecko 1.9.2 支持异步,Firefox 3.6 使用的布局引擎)
The question is does
s.async = true
have a use for dynamically inserted scripts, or are these loaded asynchronously already. The answer is they aren't loaded asynchronously in all browsers, as explained here (thanks to Markus Olsson for the link)In browsers that support
async
but don't already default to asynchronous loading (for example, Firefox 3.6),async = true
makes a difference.(The above link confirms that async is supported in Gecko 1.9.2, the layout engine used by Firefox 3.6)
规范(现在)规定
脚本< 未解析器插入的 /code> 元素是异步的;
async
属性与非解析器插入的script
元素无关:当然,拥有
async
内容属性确实意味着脚本将异步执行。规范语言似乎留下了强制同步执行脚本的机会(通过设置属性然后删除它),但实际上这不起作用,并且可能只是在规格非解析器插入的script
元素是异步的。这种指定的行为是 IE 和 Chrome 一直在做的事情,Firefox 已经做了很多年,当前的 Opera 也是这样做的(我不知道它何时从上面链接的答案中的旧行为改变)。
它很容易测试:
...with
script.js
is...将记录
The specification (now) dictates that a
script
element that isn't parser-inserted is async; theasync
property is irrelevant to non-parser-insertedscript
elements:Having the
async
content attribute does, of course, mean the script would be executed asynchronously. The spec language seems to 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-insertedscript
elements are async.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).
It's easily tested:
...with
script.js
being...will log
有趣的是——我认为事实证明我的假设是错误的。
基于 jQuery 开发者论坛中的此主题:
http ://forum.jquery.com/topic/jquery-ajax-async-vs-html5-script-async
看起来
async
属性被发现对动态有影响- 附加脚本,至少在 Firefox 中(可能还有 Opera,尽管它还不支持该属性)。论坛帖子还引用了 Google 的异步跟踪代码实现,尽管它似乎在适当的上下文中使用了
async
属性,但实际上似乎语法错误。谷歌使用:当显然这不起作用时;正确的方法是使用:
或
因此,根据我目前的理解,并非所有浏览器在所有情况下都会在插入 DOM 后立即执行动态附加脚本; Firefox(最终是 Opera)将需要设置
async
属性以确保这种情况始终发生。有关 Firefox 异步实现的更多信息,请访问:
https:// bugzilla.mozilla.org/show_bug.cgi?id=503481
Interesting - I think it turns out that I was wrong in my assumptions.
Based on this thread in the jQuery developers' forum:
http://forum.jquery.com/topic/jquery-ajax-async-vs-html5-script-async
it looks like the
async
property 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).The forum thread also cites Google's asynchronous tracking code implementation, which, although it appears to make use of the
async
property in the appropriate context, actually appears to get the syntax wrong. Google uses:when apparently that doesn't work; the proper method would be to use either:
or
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
async
property to be set to ensure that this always happens.More info on Firefox's implementation of
async
here:https://bugzilla.mozilla.org/show_bug.cgi?id=503481
我相信你是对的。
在 Steve 自己的示例中,他没有设置将 script 标签附加到 head 元素之前的 async 属性。
我对 异步属性 的理解是,它是一个向浏览器发出信号的方式,表明您不打算使用 document.write 来操作页面,以便它可以继续呈现而不是停止加载脚本。请参阅 mdc 上的脚本元素 的文档,其中包含有关document.write/异步问题。
请注意,使用您的技术,您无论如何都不应该使用 document.write,因为您无法知道脚本将在页面生命周期中的何处加载。
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.
设置
"async"
属性可以通过以下方式完成:请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute#examples
删除
"async"
属性可以通过以下方式完成:Setting the
"async"
attribute can be done with:see: https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute#examples
Removing the
"async"
attribute can be done with: