JS中的async和defer属性详解
在HTML中,<script>标签的async和defer属性用于控制外部JavaScript文件的加载和执行行为,这对页面性能有重要影响。
基本行为对比
| 属性 | 加载时机 | 执行时机 | 执行顺序保证 |
|---|---|---|---|
| 无属性 | 立即停止HTML解析加载 | 加载完成后立即执行 | 按文档顺序 |
async | 异步加载 | 加载完成后立即执行 | 不保证顺序 |
defer | 异步加载 | HTML解析完成后,DOMContentLoaded前执行 | 按文档顺序 |
详细说明
1. 无任何属性(默认行为)
<script src="script.js"></script>
-
行为:
- 遇到script标签时,暂停HTML解析
- 立即下载脚本文件
- 下载完成后立即执行脚本
- 脚本执行完成后继续HTML解析
-
影响:
- 会阻塞页面渲染
- 可能导致用户看到空白页面时间延长
2. async属性
<script async src="script.js"></script>
-
行为:
- 异步下载脚本(不阻塞HTML解析)
- 下载完成后立即执行(可能中断HTML解析)
- 多个async脚本的执行顺序不确定(先下载完的先执行)
-
适用场景:
- 完全独立的第三方脚本(如广告、分析工具)
- 不依赖DOM或其他脚本的代码
- 对执行顺序无要求的脚本
3. defer属性
<script defer src="script.js"></script>
-
行为:
- 异步下载脚本(不阻塞HTML解析)
- 在所有HTML解析完成后,DOMContentLoaded事件前按文档顺序执行
- 保证多个defer脚本的执行顺序
-
适用场景:
- 需要操作DOM的脚本
- 有依赖关系的多个脚本
- 希望延迟执行但不阻塞页面渲染的情况
简单的图示说明
无属性: [下载][执行] (阻塞HTML解析)
async: [下载]...[执行] (下载不阻塞,执行可能阻塞)
defer: [下载].........[执行] (都不阻塞,最后顺序执行)
现代最佳实践
- 关键脚本:无属性或内联,放在
<body>底部 - 非关键脚本:使用
defer - 完全独立脚本:使用
async - 模块化脚本:使用
<script type="module">(默认具有defer行为)
注意事项
defer脚本按照在文档中的顺序执行async脚本无法保证执行顺序- 同时使用
async和defer时,现代浏览器会优先async - 动态创建的
<script>元素默认具有async行为 type="module"的脚本默认具有defer行为,可以添加async属性改变行为
1775

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



