在 <script> 标签中,defer 和 async 都是用于异步加载脚本的属性,主要区别在于执行时机。
| 属性 | 下载时机 | 执行时机 | 执行顺序 | 是否阻塞 HTML 解析 |
|---|---|---|---|---|
| <无属性> | 立即下载 (阻塞) | 下载完立即执行 | 按文档顺序 | 是 (下载和执行都阻塞) |
| async | 异步下载 (不阻塞) | 下载完立即执行 | 不保证 (谁先下完谁执行) | 是 (仅执行时阻塞) |
| defer | 异步下载 (不阻塞) | HTML 解析完成后DOMContentLoaded 之前 | 保证 (按文档顺序) | 否 (完全不阻塞) |
async 脚本,会开启线程异步下载,不阻塞 HTML 解析。但是一旦下载完成,会立即暂停 HTML 解析来执行脚本。DOMContentLoaded 事件触发之前)才执行。推荐使用 defer。
因为它最接近我们将 <script> 放在 <body>底部的效果,既能并行下载提高速度,又能保证执行顺序,且不阻塞页面渲染。
按照它们在 HTML 中出现的顺序执行。
不确定。谁先下载完谁先执行。所以如果 b.js 依赖 a.js,千万不能用 async。
document.createElement('script') 创建的脚本,默认是 async 的(即异步加载并尽快执行)。如果需要顺序执行,需设置 .async = false。