是“异步”吗?如果脚本动态添加到 DOM,属性/属性有用吗?

发布于 2024-09-13 02:06:50 字数 686 浏览 13 评论 0原文

这个问题有点与 哪些浏览器支持

我最近看到一些脚本做了这样的事情:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

握住我的手 2024-09-20 02:06:50

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

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

在支持 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)

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.

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)

追风人 2024-09-20 02:06:50

规范(现在)规定脚本< 解析器插入的 /code> 元素是异步的; async 属性与非解析器插入的 script 元素无关:

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

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

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

它很容易测试:

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

...with script.js is

console.log("script loaded");

...将记录

a
b
script loaded

The specification (now) dictates that a script element that isn't parser-inserted is async; the async property is irrelevant to non-parser-inserted script elements:

The third is a flag indicating whether the element will "force-async". Initially, script elements must have this flag set. It is unset by the HTML parser and the XML parser on script elements they insert. In addition, whenever a script element whose "force-async" flag is set has a async content attribute added, the element's "force-async" flag must be unset.

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-inserted script 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:

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

...with script.js being

console.log("script loaded");

...will log

a
b
script loaded
剪不断理还乱 2024-09-20 02:06:50

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

基于 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 异步实现的更多信息,请访问:

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:

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 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

筱果果 2024-09-20 02:06:50

我相信你是对的。

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.

我很OK 2024-09-20 02:06:50

设置 "async" 属性可以通过以下方式完成:

element.setAttribute("async","")
element.setAttribute("async","anystring")

请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute#examples

删除 "async" 属性可以通过以下方式完成:

element.removeAttribute("async")

Setting the "async" attribute can be done with:

element.setAttribute("async","")
element.setAttribute("async","anystring")

see: https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute#examples

Removing the "async" attribute can be done with:

element.removeAttribute("async")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文