> For the complete documentation index, see [llms.txt](https://mm.ricky.moe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mm.ricky.moe/network/liu-lan-qi/defer-async-jiao-ben.md).

# defer, async 脚本

![蓝色线代表网络读取，红色线代表执行时间，绿色线代表 HTML 解析。](/files/-Ly7l9Mw_YK0Ovs2x0yi)

## defer

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

## async

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

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

## 结论

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

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

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

   * 评论框
   * 代码语法高亮

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