你能在HTML标签上同时使用async和defer属性吗?

m4pnthwp  于 2023-04-27  发布在  其他
关注(0)|答案(6)|浏览(133)

我想使用deferasync加载以下JavaScript代码:
<script defer async src="/js/somescript.js"></script>
由于defer是由Internet Explorer 5.5+支持的,正如你可以在www.example.com上看到CanIUse.com,如果async不可用,我想优雅地回退到使用defer。我认为异步更好地使用时,它是可用的,但它不支持,直到Internet Explorer 10。
因此,我的问题是上面的代码是否有效的HTML?如果不是,当async不可用时,是否可以使用JavaScript创建这种情况,优雅地回退到脚本上使用defer

li9yvcax

li9yvcax1#

从规范:https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
即使指定async属性,也可以指定defer属性,以使仅支持defer(而不异步)的旧式Web浏览器回退到defer行为而不是默认的同步阻塞行为。

  • (查看下面的参考链接,以查看普通脚本与具有defer和async的脚本之间差异的可视化表示)*

参考文献:

mzaanser

mzaanser2#

问题是,你希望它做什么?如果asyncdefer都存在,我希望脚本被延迟,并且只在浏览器空闲时在DOMContentLoaded之后执行,但如果我正确阅读规范,它看起来像defer被忽略,如果async被设置并且脚本被异步加载,那么将在它可用时立即执行,其很可能在DOMContentLoaded之前并且可能阻塞其它资源。
使用这些属性可以选择三种可能的模式。如果存在async属性,则脚本将在其可用时立即异步执行。如果不存在async属性,但存在defer属性,则脚本将在页面完成解析后执行。如果两个属性都不存在,则脚本将立即获取并执行。在用户代理继续解析页面之前。
https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

s8vozzvw

s8vozzvw3#

不幸的是,当指定async时,defer被忽略,并且async总是具有更高的优先级。
就我个人而言,我认为忽略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中。

suzh9iv8

suzh9iv84#

是的,它是有效的HTML,它会像预期的那样工作。
任何符合W3C标准的浏览器都可以识别 async 属性并正确处理脚本,而传统的 IE 版本可以识别 defer 属性。
因为这两个属性都是布尔型的,所以你不需要给它们赋值。

fzwojiic

fzwojiic5#

不需要。你需要使用defer或async,但不能同时使用。更多信息请查看比较,并根据需要使用其中一个。

**defer属性:**先下载脚本文件,然后等待html解析,html解析结束后执行脚本,也就是说,保证所有的脚本在html解析后都能执行。

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

**async属性:**不等待html解析结束,直接下载脚本文件执行,也就是说不保证html解析结束后所有脚本都能执行。

Async属性在脚本不用于DOM操作时很有用。有时您只需要脚本进行服务器端操作或处理缓存或cookie,而不需要DOM操作。这意味着脚本与所使用的html无关。

ctrmrzij

ctrmrzij6#

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

相关问题