提问人:Johny P. 提问时间:10/27/2017 最后编辑:Heretic MonkeyJohny P. 更新时间:9/29/2020 访问量:3812
使用 async 和 defer 按顺序加载脚本
Using async and defer to load scripts in order
问:
因此,我正在遵循 Google PageSpeed 的建议来推迟首屏脚本。假设这是我的代码:<head>
<script src="/js/jquery.js"></script>
<script src="/js/functions.js"></script>
该脚本依赖于 jQuery,因此在 之前加载和执行至关重要。functions.js
jquery.js
functions.js
我尝试过:
推迟
<script src="/js/jquery.js" defer></script>
<script src="/js/functions.js" defer></script>
虽然这可以正常工作并正确执行,但当我加载页面时,我看到它闪烁,就好像 CSS 尚未加载一样。请注意,上面的代码位于 .如果我从中删除该属性,闪烁就会消失。这就引出了我的问题:functions.js
<head>
defer
jquery.js
混合
<script src="/js/jquery.js" async></script>
<script src="/js/functions.js" defer></script>
在依赖脚本和依赖脚本上使用是否确保它们始终按该顺序执行?它似乎在我的测试中有效,但我对解析器的工作原理了解不够,无法确定。async
defer
答:
是的,在 chrome 上,有时在 Firefox 上。.
规范说它们将按顺序加载,但加载意味着下载不执行,因此如果文件在其他文件之前完成下载,它将首先运行,因此我不建议您使用 defer 或 async 属性依赖执行顺序
答案是,如果您使用 或 ,您将失去对执行脚本的顺序的保证。async
defer
async
脚本是异步执行的,不能保证有哪个顺序。 脚本在文档解析后执行,但不能保证它们是否会按顺序执行。(具体看一下这个关于延迟
脚本的问题。defer
不幸的是,在您的情况下,您必须通过删除 and 属性来同步运行。jquery.js
defer
async
展望未来,当我们转向模块时,指定依赖项并及时(并且仅加载一次)将变得更加容易。
评论
async
defer
load
<script>
虽然我不确定当前的浏览器是如何实现该标准的,但对脚本(没有 type=“module”的经典脚本元素)和模块(带有 type=module 的脚本元素)的执行顺序有最低限度的保证。
1) 未指定 defer 或 async 的经典脚本将按照它们在 html 文档中出现的顺序执行(在解析文档时)。它们在延迟的经典脚本和非异步模块之前执行。
2) 延迟的经典脚本和非异步模块按照它们在 HTML 文档中出现的顺序执行(在文档解析后)。
请参阅此处有关处理模型的第 20 点:https://www.w3.org/TR/html5/semantics-scripting.html#script-processing-model
评论