我想使用defer
和async
加载以下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
?
6条答案
按热度按时间li9yvcax1#
从规范:https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
即使指定async属性,也可以指定defer属性,以使仅支持defer(而不异步)的旧式Web浏览器回退到defer行为而不是默认的同步阻塞行为。
参考文献:
mzaanser2#
问题是,你希望它做什么?如果async和defer都存在,我希望脚本被延迟,并且只在浏览器空闲时在DOMContentLoaded之后执行,但如果我正确阅读规范,它看起来像defer被忽略,如果async被设置并且脚本被异步加载,那么将在它可用时立即执行,其很可能在DOMContentLoaded之前并且可能阻塞其它资源。
使用这些属性可以选择三种可能的模式。如果存在async属性,则脚本将在其可用时立即异步执行。如果不存在async属性,但存在defer属性,则脚本将在页面完成解析后执行。如果两个属性都不存在,则脚本将立即获取并执行。在用户代理继续解析页面之前。
https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async
s8vozzvw3#
不幸的是,当指定
async
时,defer
被忽略,并且async
总是具有更高的优先级。就我个人而言,我认为忽略
defer
是非常糟糕的。让我们想象一下,当我们希望有一些JS尽快初始化的情况,甚至在加载页面内容之前。但是我们希望这个脚本在其他需要它的脚本之前初始化。它应该在defer
队列中的第一个。但是,不幸的是,这不会起作用:在这个示例中,“some_jquery_plugin.min.js”可以在jQuery加载之前加载并执行,并且会失败。:(
因此,有两种方法可以解决这个问题:要么只使用
defer
指令,要么将所有依赖的javascript文件合并到单个JS中。suzh9iv84#
是的,它是有效的HTML,它会像预期的那样工作。
任何符合W3C标准的浏览器都可以识别 async 属性并正确处理脚本,而传统的 IE 版本可以识别 defer 属性。
因为这两个属性都是布尔型的,所以你不需要给它们赋值。
fzwojiic5#
不需要。你需要使用defer或async,但不能同时使用。更多信息请查看比较,并根据需要使用其中一个。
**defer属性:**先下载脚本文件,然后等待html解析,html解析结束后执行脚本,也就是说,保证所有的脚本在html解析后都能执行。
当脚本用于DOM操作时,Defer属性很有用。这意味着脚本将应用于文档html。
**async属性:**不等待html解析结束,直接下载脚本文件执行,也就是说不保证html解析结束后所有脚本都能执行。
Async属性在脚本不用于DOM操作时很有用。有时您只需要脚本进行服务器端操作或处理缓存或cookie,而不需要DOM操作。这意味着脚本与所使用的html无关。
ctrmrzij6#
实际上,这里的大多数评论都有一个误解。人们似乎不知道DEFER也并行加载代码,就像ASYNC一样。但是它在DOM加载之后(但在DOMContentLoaded执行之前)等待执行,而ASYNC在加载之后,DOM加载之前立即运行它。由于ASYNC和DEFER都并行加载代码,因此没有必要一起使用两者(但可能是为了处理遗留问题)。