script 标签中 defer 和 async 的区别
在 <script>
标签中,defer
和 async
是两个用于控制 JavaScript 脚本加载和执行行为的属性。它们的主要区别在于加载顺序和执行时机。具体如下:
1. defer
属性
- 加载方式: 使用
defer
的脚本在 HTML 解析的同时异步加载。 - 执行顺序: 所有带有
defer
的脚本会按照它们在页面中的出现顺序依次执行。 - 执行时机: 脚本会在 HTML 文档解析完毕后执行,也就是在
DOMContentLoaded
事件触发之前,但不会阻塞页面的解析。 - 适用场景: 当脚本依赖于 DOM 结构时,使用
defer
是理想的,因为它保证了脚本执行时 DOM 已经完全加载完成。
例子:
<script src="example.js" defer></script>
2. async
属性
- 加载方式: 使用
async
的脚本也会异步加载,与 HTML 解析同时进行。 - 执行顺序: 脚本会在加载完成后立即执行,不保证按照它们在页面中的出现顺序执行。
- 执行时机: 一旦脚本加载完成,就会立即执行,可能会在 HTML 解析完成之前执行,也可能在解析过程中执行。
- 适用场景: 用于独立、不依赖于其他脚本或 DOM 内容的脚本,例如分析工具或广告脚本,因为它们可以尽快执行而不影响页面的解析。
例子:
<script src="example.js" async></script>
区别总结:
- 加载顺序:
async
无序(哪个脚本先加载完哪个先执行),defer
有序(按照 HTML 中的顺序执行)。 - 执行时机:
async
脚本一旦加载完成立刻执行,defer
脚本会在 HTML 解析完成之后执行。
执行时机图示:
- 普通
<script>
标签:同步加载,立即阻塞 HTML 解析,加载完毕后执行。 defer
脚本:异步加载,不阻塞 HTML 解析,等 HTML 全部解析完后按顺序执行。async
脚本:异步加载,不阻塞 HTML 解析,但加载完毕后立即执行,且无序。
哪个更好?
- 当脚本依赖于页面的 DOM 结构时,使用
defer
更安全。 - 当脚本与其他脚本和页面结构无关时,可以使用
async
以加快加载和执行速度。