您可以在HTML脚本标记上同时使用async和defer属性吗?

时间:2012-12-11 13:10:27

标签: javascript html5 asynchronous

我想使用deferasync加载以下JavaScript代码:

<script defer async src="/js/somescript.js"></script>

由于Internet Explorer 5.5+支持defer,正如您在CanIUse.com所看到的那样,如果async不可用,我希望优先使用defer。 Async我认为最好在可用时使用,但在Internet Explorer 10之前不支持。

我的问题是上面的代码是否有效HTML?如果没有,是否可以使用JavaScript在defer不可用时优雅地回退到脚本上使用async来创建这种情况?

5 个答案:

答案 0 :(得分:99)

来自规范:https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

  

即使指定了async属性,也可以指定defer属性,以使仅支持延迟(而非异步)的旧版Web浏览器回退到延迟行为,而不是默认的同步阻塞行为。 / p>

答案 1 :(得分:13)

问题是,您期望它做什么? 如果异步延迟都存在,我希望脚本延迟并且只在浏览器空闲时在DOMContentLoaded之后执行,但如果我正在阅读规范如果设置了 async 并且异步加载脚本,则会忽略延迟,因此一旦可用就会执行,这可能在之前很久就会执行DOMContentLoaded并可能阻止其他资源。

  

使用这些属性可以选择三种可能的模式。如果存在async属性,则脚本一旦可用就会异步执行。如果async属性不存在但是存在defer属性,则在页面完成解析时执行脚本。如果两个属性都不存在,则在用户代理继续解析页面之前立即获取并执行脚本。

https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

答案 2 :(得分:8)

是的,它有效的HTML,它会像预期的那样工作。

任何符合W3C标准的浏览器都会识别 async 属性并正确处理脚本,而旧版 IE 版本将识别 defer 属性。< / p>

由于两个属性都是 boolean ,因此不必分配任何值。

答案 3 :(得分:1)

实际上,这里的大多数评论都存在误解。人们似乎不知道 DEFER 也像 ASYNC 一样并行加载代码。但是它会在 DOM 加载后(但在 DOMContentLoaded 执行之前)等待执行,而 ASYNC 在加载后立即运行,在 DOM 加载之前。由于 ASYNC 和 DEFER 并行加载代码,因此无需同时使用两者(但可能是为了处理遗留问题)。

答案 4 :(得分:0)

不幸的是,当指定deferasync被忽略,并且async始终具有更高的优先级。 (至少在Chrome中。老实说,未在其他浏览器中进行过测试,但我认为结果将是相同的。)

我个人认为defer被忽略是非常糟糕的。让我们想象一下在加载页面内容之前,我们希望尽快进行一些JS初始化的情况。但是我们希望此脚本在需要它的其余脚本之前进行初始化。它应该位于defer队列中的第一位。但是,不幸的是,这行不通:

<!-- we want "jQuery" ASAP and still in "defer" queue. But defer is ignored. -->
<script src="jquery.min.js" async defer></script>

<!-- this doesn't blocks the content and can wait the full page load, but requires "jQuery" -->
<script src="some_jquery_plugin.min.js" defer></script>

在此示例中,“ some_jquery_plugin.min.js”可以在加载jQuery之前加载并执行,并且将失败。 :(

因此,有两种方法可以解决此问题:要么仅使用defer指令,要么将所有依赖的javascript文件合并到单个JS中。