web性能优化基础篇之 async 与 defer 的区别

560 阅读2分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

普通标签的js

在解析 HTML 的过程中,遇到了一个普通的 script 标签,那么此时会下载 js,并中断 HTML 的解析,若下载 js 的时间太长,会等到下载完 js 才会执行 js,在执行完 js 后才会出现 DOM ready 事件。

含有 defer 的js

在解析 HTML 的过程中,遇到了一个含有 deferscript 标签,那么此时会下载 js,并且继续解析 HTML,若下载 js 的时间太长,会等到下载完 js 才会执行,在执行完 js 后才会出现 DOM ready 事件。

image.png

  1. deferjs 的下载和 HTML 的解析可以同时进行,没有提前下载 js
  2. defer 保证 js 的执行是在 HTML 解析之后,DOM ready之前。
  3. 如果有两个或多个 deferjs,执行顺序是按照代码写的顺序执行,都执行完后才会触发 DOM ready 事件。
  4. <script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。

async

在解析 HTML 的过程中,遇到了一个含有 asyncscript 标签,那么此时会下载 js,并且继续解析HTML,若下载 js 的时间太长,会等到下载完 js 才会执行 js,但是在 HTML 解析完后就会出现 DOM ready 事件。

image.png

  1. asyncjs 的下载和 HTML 的解析可以同时进行,并且把两个流程隔离开来。
  2. 如果有两个或多个 asyncjs,只要下载完就会去执行,跟代码写的先后顺序无关,因此要确保多个 js 之间没有相互依赖关系比较重要。
  3. 如果 asyncjs 下载的速度比较快,会中断 HTML 的解析,因为它是下载完就执行了。

总结

从上面的介绍可以得到,async 是乱序的,它使得解析 HTML 和下载执行 js 之间的关系变得更加松散,因此,async 比较适用于百度分析或者谷歌分析这类不依赖其他脚本的库。defer 是顺序执行,可以按照写入的顺序先后执行,但是 js 的下载并不影响 HTML 的解析。所以通常的代码中很少用到 async

一个普通的<script>标签的加载和解析都是同步的,会阻塞DOM的渲染,这也就是我们经常会把<script>写在<body>底部的原因之一,为了防止加载资源而导致的长时间的白屏,另一个原因是js可能会进行DOM操作,所以要在DOM全部渲染完后再执行。

最后说一句

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。