因此,我遵循Google PageSpeed建议推迟使用首字母缩略词。假设这是我<head>
中的代码:
<script src="/js/jquery.js"></script>
<script src="/js/functions.js"></script>
functions.js
脚本依赖于jQuery,因此在jquery.js
之前加载并执行functions.js
至关重要。
延迟
<script src="/js/jquery.js" defer></script>
<script src="/js/functions.js" defer></script>
虽然这有效并且functions.js
正确执行,但当我加载页面时,我看到它闪烁,好像CSS尚未加载。请注意,上面的代码位于<head>
。如果我从defer
中删除jquery.js
属性,则闪烁消失。这引出了我的问题:
混合
<script src="/js/jquery.js" async></script>
<script src="/js/functions.js" defer></script>
在依赖脚本上使用async
并在依赖脚本上使用defer
确保它们始终按该顺序执行吗?它似乎在我的测试中起作用,但我不太了解解析器如何工作以确保。
答案 0 :(得分:1)
答案是,如果您使用async
或defer
,则会失去有关订单脚本执行的保证。
async
脚本是异步执行的,无法保证顺序。 defer
脚本在文档解析后执行,但不能保证它们是否将按顺序执行。 (具体看看this question about defer
scripts。)
不幸的是,在您的情况下,必须通过删除jquery.js
和defer
属性来同步运行async
。
展望未来,当我们进入模块时,指定依赖项并及时(且仅一次)加载它们将变得更加容易。
答案 1 :(得分:1)
尽管我不确定当前的浏览器如何实现该标准,但是对于脚本(没有type =“ module”的经典脚本元素)和模块(带有type = module的脚本元素)的执行顺序几乎没有保证。
1)不指定延迟或异步的经典脚本按它们在html文档中出现的顺序(在解析文档时)执行。它们在延迟的经典脚本和非异步的模块之前执行。
2)延迟的经典脚本和非异步的模块按照它们在html文档中出现的顺序(在文档解析后)执行。
请参见此处的处理模型第20点:https://www.w3.org/TR/html5/semantics-scripting.html#script-processing-model
答案 2 :(得分:0)
是Chrome,有时在Firefox上。
规格说它们将按顺序加载,但加载的意思是下载没有执行,所以如果文件完成下载之前它会先运行,所以我不建议你依赖于使用延迟或异步属性的执行顺序