通过延迟和异步有效地加载JavaScript

在HTML页面上加载脚本时,需要注意不要损害页面的加载性能。取决于将脚本添加到HTML页面的位置和方式,将影响加载时间

在HTML页面上加载脚本时,需要注意不要损害页面的加载性能。

传统上,脚本是通过以下方式包含在页面中的:

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

只要HTML解析器找到这一行,就会请求获取脚本,并执行脚本。

一旦完成此过程,就可以继续进行解析,然后可以分析HTML的其余部分。

您可以想象,此操作可能会对页面的加载时间产生巨大影响。

如果脚本的加载时间比预期的要长一点,例如,如果网络有点慢,或者您使用的是移动设备,并且连接有点草率,则访问者可能会看到空白页,直到脚本被加载为止。加载并执行。

位置很重要

初学HTML时,系统会告诉您脚本标签实时存在于<head>标签:

<html>
  <head>
    <title>Title</title>
    <script src="script.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

正如我之前告诉您的那样,当解析器找到这一行时,它将去获取脚本并执行它。然后,完成此任务后,它将继续解析正文。

这很糟糕,因为引入了很多延迟。解决此问题的一种非常常见的方法是将script标签位于页面底部,紧接在结束之前</body>标签。

这样做时,在所有页面都已被解析和加载之后,脚本便被加载并执行,这是一个巨大的进步head选择。

如果需要支持不支持HTML的两个相对较新的功能的旧版浏览器,这是最好的选择。asyncdefer

异步和延迟

异步和延迟都是布尔属性。它们的用法类似:

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

如果您同时指定,async在现代浏览器上优先,而支持该功能的旧版浏览器defer但不是async将回退到defer

有关支持表,请访问caniuse.com以获取异步信息https://caniuse.com/#feat=script-async并推迟https://caniuse.com/#feat=script-defer

仅当在head页面的一部分,如果您将脚本放在body就像我们在上面看到的页脚。

性能比较

头部无延迟或异步

这是网页在不延迟或异步的情况下加载脚本的方式,head页面的一部分:

Without defer or async, in the head

暂停解析,直到提取并执行脚本。完成此操作后,将继续解析。

体内没有延迟或异步

这是网页加载脚本时没有延迟或异步的方式,该脚本位于body标签,就在它关闭之前:

Without defer or async, in the body end

解析没有任何暂停即可完成,完成后,将提取并执行脚本。解析是在脚本下载完成之前完成的,因此该页面以用户的方式显示在上一个示例之前。

与异步,在头上

这是网页加载脚本的方式async,放在head标签:

With async

该脚本是异步获取的,准备就绪后,HTML解析将暂停以执行该脚本,然后将其恢复。

延后,在头上

这是网页加载脚本的方式defer,放在head标签:

With defer

该脚本是异步获取的,只有在HTML解析完成后才执行。

解析完成就像我们将脚本放在末尾一样body标记,但总体而言,脚本执行早于完成,因为脚本是与HTML解析同时下载的。

所以这是速度方面的制胜法宝🏆

阻止解析

async阻止页面解析,而defer才不是。

阻止渲染

两者都不async也不defer确保在阻止渲染时采取任何措施。这取决于您和您的脚本(例如,确保脚本在onLoad) 事件。

dom互动

标记脚本defer在之后执行domInteractive事件,发生在HTML加载,解析并DOM建成。

此时的CSS和图像仍然需要解析和加载。

完成此操作后,浏览器将发出domComplete事件,然后onLoad

domInteractive之所以重要,是因为它的时间被认为是感知加载速度的量度。查看MDN更多。

保持秩序

另一个案例defer:标记的脚本async当它们可用时,将以随意的顺序执行。标记脚本defer(在解析完成之后)按照标记中定义的顺序执行。

告诉我最好的方法

使用脚本时,加快页面加载速度的最佳方法是将其放入head,然后添加一个defer归因于您script标签:

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

这是触发更快的情况domInteractive事件。

考虑到的优点defer,似乎是一个更好的选择async在各种情况下。

除非可以延迟页面的第一次渲染,否则请确保在解析页面时,所需的JavaScript已经执行。

免费下载我的JavaScript初学者手册


更多浏览器教程: