理解script标签async和defer的原理

208 阅读1分钟

简述概念

<script>标签的引入资源方式有三种,有一种就是我们常用的直接引入,还有两种就是使用 async 属性和 defer 属性来异步引入,两者都是去异步加载外部的JS文件,不会阻塞DOM的解析(尽量使用异步加载)。三者的区别如下:

  • script 立即停止页面渲染去加载资源文件,当资源加载完毕后立即执行js代码,js代码执行完毕后继续渲染页面;
  • async 异步加载资源,加载好后立即执行,多个带async属性的标签,不能保证加载的顺序;
  • defer 异步加载资源,加载好后,如果 DOM 树还没构建好,则先等 DOM 树解析好再执行;如果DOM树已经准备好,则立即执行。多个带defer属性的标签,按照顺序执行。

思考使用场景

async的原理

  • 普通script标签同步串行,第一个标签请求资源 执行脚本,第二个请求资源 执行脚本。
  • 比起普通script标签,async的异步请求节省了script标签之间等待网络请求的时间。
  • async script的执行是无序的,谁先请求回来谁先执行。
  • async是有可能会阻塞dom css资源的加载以及后续dom树的构建(它异步请求回来资源后会立即执行,即使dom css资源未加载完成)。

defer的原理

defer script会异步请求资源,并保证script标签的执行顺序。执行的时机会在DOM树构建好之后,在DOMContentLoaded钩子之前。

验证上边两点的一幅图

wecom-temp-6b2bf7002521cb37bbbaa300a14c8878.png