文章目录
- [<script>元素中的 defer 和 async 属性详解](#<script>元素中的 defer 和 async 属性详解)
在HTML5中,<script>
元素有两个控制脚本加载和执行行为的属性:defer
和 async
。这两个属性可以帮助开发者优化页面加载性能,特别是在处理外部脚本时。
基本概念
传统脚本加载
没有使用任何属性的 <script>
元素会阻塞HTML解析:
html
<script src="script.js"></script>
- 浏览器遇到这个脚本时会暂停HTML解析
- 下载并执行脚本
- 执行完成后才继续解析HTML
defer 属性
html
<script defer src="script.js"></script>
- 异步下载:不阻塞HTML解析,脚本在后台下载
- 延迟执行:脚本会在HTML文档完全解析后,DOMContentLoaded事件触发前执行
- 保持顺序:多个defer脚本会按照它们在文档中出现的顺序执行
async 属性
html
<script async src="script.js"></script>
- 异步下载:不阻塞HTML解析,脚本在后台下载
- 立即执行:脚本一旦下载完成就立即执行(可能会中断HTML解析)
- 不保证顺序:多个async脚本不能保证执行顺序,先下载完成的先执行
对比表格
特性 | 无属性 | defer | async |
---|---|---|---|
阻塞HTML解析 | 是 | 否 | 否 |
执行时机 | 立即 | DOM解析完成后 | 下载完成后立即 |
执行顺序 | 顺序 | 顺序 | 不确定 |
适合场景 | 必须立即执行的脚本 | 依赖DOM的脚本 | 独立模块,不依赖其他脚本 |
使用场景建议
-
使用 defer:
- 脚本需要访问完整的DOM
- 脚本依赖于其他脚本(需要保持执行顺序)
- 示例:页面初始化脚本、DOM操作库
-
使用 async:
- 脚本完全独立,不依赖其他脚本
- 不操作DOM或可以等待
- 示例:统计分析代码、广告脚本
-
不使用任何属性:
- 脚本很小且必须立即执行
- 脚本对页面渲染至关重要(如首屏关键功能)
注意事项
- 这两个属性只对外部脚本(有src属性的脚本)有效,对内联脚本无效
- 如果同时使用
defer
和async
,现代浏览器会优先采用async
的行为 - defer脚本保证在
DOMContentLoaded
事件前执行 - 使用这些属性时,脚本不应使用
document.write
,因为文档可能已经解析完成
示例
html
<!DOCTYPE html>
<html>
<head>
<!-- 不影响DOM解析的独立脚本 -->
<script async src="analytics.js"></script>
<!-- 需要DOM就绪且保持顺序的脚本 -->
<script defer src="jquery.js"></script>
<script defer src="app.js"></script>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>
通过合理使用 defer 和 async 属性,可以显著提高页面加载性能,特别是对于包含多个脚本的页面。