93

我想同时使用defer和加载以下 JavaScript 代码async

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

由于deferInternet Explorer 5.5+ 支持,正如您在CanIUse.com上看到的那样,如果异步不可用,我想优雅地回退到使用 defer。我认为异步在可用时使用更好,但直到 Internet Explorer 10 才支持它。

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

4

6 回答 6

135

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

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

(查看下面的参考链接,以直观的方式展示普通脚本与具有延迟和异步的脚本之间的差异)


参考:

于 2012-12-11T13:15:23.117 回答
22

问题是,你希望它做什么?如果asyncdefer都存在,我希望脚本被延迟并​​且仅在浏览器空闲时在 DOMContentLoaded 之后执行,但是如果我正在阅读规范,那么如果设置了async并且脚本被加载,则看起来defer被忽略异步的,所以一旦可用就会立即执行,这很可能在 DOMContentLoaded 之前执行,并且可能会阻塞其他资源。

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

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

于 2017-01-06T10:10:39.147 回答
13

不幸的是在指定defer时被忽略,并且总是具有更高的优先级。asyncasync

我个人认为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 中。

于 2019-03-28T01:51:03.640 回答
10

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

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

由于这两个属性都是布尔值,因此您不必分配任何值。

于 2012-12-11T13:15:04.053 回答
5

是的,您可以使用这两个属性,但您需要使用 defer 或 async,而不是两者。有关更多信息,请参阅比较并根据您的需要使用一个。

defer 属性:首先它会下载脚本文件,然后等待 html 解析。html解析结束后,将执行脚本。换句话说,它将保证所有脚本在 html 解析后执行。

当脚本用于 DOM 操作时,延迟属性很有用。意味着脚本将应用于文档 html。

async 属性:它将下载脚本文件并执行,无需等待 html 解析结束。换句话说,它不能保证所有的脚本都会在 html 解析之后执行。

当脚本不用于 DOM 操作时,异步属性很有用。有时您只需要脚本用于服务器端操作或处理缓存或 cookie,而不需要用于 DOM 操作。表示脚本与使用的 html 无关。

在此处输入图像描述

于 2021-08-25T20:10:31.633 回答
1

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

于 2021-03-13T04:54:06.467 回答