JavaScript中defer与async的区别详解
在JavaScript中,<script>标签的defer和async属性用于优化脚本加载和执行机制,避免阻塞页面渲染。两者的核心区别在于脚本的执行时机和顺序控制,具体分析如下:
一、加载与执行机制
-
加载方式
- 共同点:两者均异步加载脚本,即不会阻塞HTML解析。
- 不同点:
defer:脚本加载完成后,会等待整个HTML文档解析完成(即DOM树构建完毕)且DOMContentLoaded事件触发前按顺序执行。async:脚本加载完成后立即执行,执行时机不确定(可能在HTML解析完成前或后),且不保证多个脚本的执行顺序。
-
执行时机示意图
- 无属性:
加载 → 执行 → 继续解析HTML(阻塞页面)。 defer:并行加载 → HTML解析完成 → 按顺序执行。async:并行加载 → 加载完成立即执行(可能中断HTML解析)。
- 无属性:
二、执行顺序与依赖管理
| 特性 | defer | async |
|---|---|---|
| 执行顺序 | 按脚本在文档中的声明顺序执行 | 加载完成顺序决定执行顺序 |
| 依赖支持 | 适合有依赖关系的脚本(如库文件+业务逻辑) | 适合独立脚本(无依赖) |
| DOM操作支持 | 保证DOM解析完成,可安全操作DOM | 可能因执行过早导致DOM操作失败 |
示例:
若需加载jQuery(依赖DOM)及其插件,应使用defer确保顺序;而统计脚本(如Google Analytics)适合async。
三、适用场景
-
defer的典型场景- 需要操作DOM的脚本(如表单验证、动态渲染)。
- 多个脚本存在依赖关系(如
library.js需在app.js前执行)。 - 替代传统“将脚本置于
</body>前”的优化方案。
-
async的典型场景- 独立第三方脚本(如广告、数据分析)。
- 不依赖DOM或其他脚本的工具库(如性能监控)。
四、注意事项
-
兼容性
defer:HTML4已支持,但部分旧浏览器可能忽略顺序。async:HTML5新增属性,需注意低版本浏览器兼容性。
-
冲突处理
- 若同时设置
defer和async,async优先级更高(现代浏览器按async处理)。
- 若同时设置
-
脚本内容限制
- 使用
defer时避免调用document.write,可能导致意外行为。
- 使用
五、总结对比表
| 特性 | defer | async |
|---|---|---|
| 加载阻塞 | 不阻塞HTML解析 | 不阻塞HTML解析 |
| 执行时机 | DOM解析完成后,按顺序执行 | 加载完成后立即执行,顺序不确定 |
| DOM依赖 | 安全操作DOM | 可能因过早执行导致DOM未就绪 |
| 适用场景 | 依赖DOM或脚本顺序的复杂逻辑 | 独立、无依赖的轻量脚本 |
通过合理选择defer或async,开发者可以优化页面加载性能,平衡脚本执行与渲染效率。若需进一步验证,可参考实际代码示例(如网页1、5中的DOM事件测试)。



1860

被折叠的 条评论
为什么被折叠?



