使用async和defer按顺序加载脚本

时间:2017-10-27 15:30:40

标签: javascript jquery asynchronous html-parsing

因此,我遵循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确保它们始终按该顺序执行吗?它似乎在我的测试中起作用,但我不太了解解析器如何工作以确保。

3 个答案:

答案 0 :(得分:1)

答案是,如果您使用asyncdefer,则会失去有关订单脚本执行的保证。

async脚本是异步执行的,无法保证顺序。 defer脚本在文档解析后执行,但不能保证它们是否将按顺序执行。 (具体看看this question about defer scripts。)

不幸的是,在您的情况下,必须通过删除jquery.jsdefer属性来同步运行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上。

规格说它们将按顺序加载,但加载的意思是下载没有执行,所以如果文件完成下载之前它会先运行,所以我不建议你依赖于使用延迟或异步属性的执行顺序