# defer, async 脚本

![蓝色线代表网络读取，红色线代表执行时间，绿色线代表 HTML 解析。](https://3490195898-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnQxDcxCKODvYvTUWe3%2F-Ly7IEDMOXg-JsDhJNBp%2F-Ly7l9Mw_YK0Ovs2x0yi%2Fimage.png?alt=media\&token=272d8abc-7845-4127-84ac-c219c515d287)

## defer

明脚本在执行时不会影响页面的构造。也就是说，脚本会被延迟到整个页面都解析完毕后再运行。因此，在`<script>`元素中设置`defer`属性，相当于告诉浏览器立即下载，但**延迟按顺序执行**。

## async

告诉浏览器**立即下载文件**。但与`defer`不同的是，标记为`async`的脚本**并不保证按照它们的先后顺序执行**。

第二个脚本文件可能会在第一个脚本文件之前执行。因此确保两者之间互不依赖非常重要。

## 结论

1. `async`是立即下载乱序执行

   async比较适用于百度分析或者谷歌分析这类不依赖其他脚本的库。
2. `defer`是延迟顺序执行

   适用于脚本代码依赖于页面中的`DOM`元素（文档是否解析完毕）

   * 评论框
   * 代码语法高亮

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