【问题标题】:Using async and defer to load scripts in order使用 async 和 defer 按顺序加载脚本
【发布时间】:2018-04-09 06:28:49
【问题描述】:

因此,我遵循 Google PageSpeed 的建议来推迟首屏脚本。假设这是我<head>中的代码:

<script src="/js/jquery.js"></script>
<script src="/js/functions.js"></script>

functions.js 脚本依赖于 jQuery,因此在 functions.js 之前加载和执行 jquery.js 至关重要。

我尝试了什么:

推迟

<script src="/js/jquery.js" defer></script>
<script src="/js/functions.js" defer></script>

虽然这有效并且functions.js 被正确执行,但当我加载页面时,我看到它闪烁,好像尚未加载 CSS。注意上面的代码在&lt;head&gt;。如果我从jquery.js 中删除defer 属性,闪烁就会消失。这引出了我的问题:

混合

<script src="/js/jquery.js" async></script>
<script src="/js/functions.js" defer></script>

在依赖脚本上使用async 并在依赖脚本上使用defer 是否确保它们始终按该顺序执行?它似乎在我的测试中有效,但我对解析器的工作方式知之甚少,无法确定。

【问题讨论】:

    标签: javascript jquery asynchronous html-parsing


    【解决方案1】:

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

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

    不幸的是,在您的情况下,您必须通过删除 deferasync 属性来同步运行 jquery.js

    展望未来,随着我们转向模块,指定依赖项并及时(且仅一次)加载它们将会变得更加容易。

    【讨论】:

    • 我还没有研究模块。也许在我的下一个项目中,我会检查 ECMAScript 标准的内容。
    • 如果不想用同步脚本block,就没有必要——用asyncdefer加载脚本,听它的load事件,一旦触发,创建另一个依赖于前一个的&lt;script&gt;,依此类推。
    【解决方案2】:

    虽然我不确定当前的浏览器是如何实现标准的,但对于脚本(没有 type="module" 的经典脚本元素)和模块(type=module 的脚本元素)的执行顺序几乎没有保证。

    1) 没有指定 defer 或 async 的经典脚本按照它们在 html 文档中出现的顺序执行(当文档被解析时)。它们在延迟的经典脚本和非异步的模块之前执行。

    2) defer 的经典脚本和非异步的模块按照它们在 html 文档中出现的顺序执行(在文档被解析之后)。

    在此处查看关于处理模型的第 20 点:https://www.w3.org/TR/html5/semantics-scripting.html#script-processing-model

    【讨论】:

      【解决方案3】:

      在 chrome 上是的,有时在 Firefox 上..

      规范说它们将按顺序加载,但加载意味着下载未执行,因此如果文件在其他文件之前完成下载,它将首先运行,因此我不建议您使用延迟或异步属性依赖执行顺序

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多