liangbus / blogging

Blog to go
10 stars 0 forks source link

script 标签的 async 和 defer #12

Open liangbus opened 4 years ago

liangbus commented 4 years ago

做题的时候,遇到一些基础性的问题时,发现对一些知识点的印象已经有点模糊了,之前也没写过相关的,就翻阅了一下资料,权当做下笔记

先来描述一下三种方式的特性:

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

  1. 普通加载,即没有 async 和 defer 的方式,当浏览器解析遇到 script 标签时,会停下来加载该 script 标签,加载完成后会立刻执行其内容,这就是我们平常所说的 script 标签会阻塞 Dom 树的构建和渲染

<script src="app.js" async><script>

  1. 浏览器遇到多了 async 属性的 script 标签之后,不会停止解析 dom 树,同时会异步加载该 script 标签,当加载完成后即执行该脚本内容,执行过程会阻塞 Dom 树渲染

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

  1. 浏览器遇到带 defer 属性的 script 标签之后,不会停止解析 Dom 树,同样是异步加载该 script 标签,但是与 async 不同的是,该脚本加载完之后不是立刻执行,而是等到 Dom 树解析完成之后再执行(DOMContentLoaded 事件触发之前)

总结一下

  1. async 与 defer 最大的不同就是下载完 script 之后对其内容的执行时机上
  2. defer 理论上是按加载顺序来执行的,而 async 则是无序,受网络影响,先到先执行(但是《JS高设》中似乎有说明该特性不严谨,不一定会按顺序执行)

所以对于页面来说,任何涉及到 dom 操作的脚本,都不应该使用 async,async script 仅适合本身完全独立,没有任何依赖的脚本