async脚本下载完立即执行,可能早于dom就绪;defer脚本等html解析完、domcontentloaded前按序执行。async不保序,defer保序;async适合独立统计脚本,defer适合依赖dom或有先后依赖的业务逻辑。

async 和 defer 都能让外部 JavaScript 脚本异步加载,避免阻塞 HTML 解析,但它们的执行时机和顺序规则完全不同。选错属性可能导致脚本执行失败或逻辑错乱,尤其在依赖 DOM 或存在先后依赖时。
执行时机不同
async 脚本一旦下载完成就立刻执行,不管 HTML 是否解析完——可能在 DOM 构建中途 就运行,此时 document 可能还不完整;defer 脚本则严格等到整个 HTML 解析完毕、DOMContentLoaded 触发前 才执行,此时 DOM 已就绪。
- async:下载完 → 立即执行(哪怕 还没读到)
- defer:下载完 → 暂存 → HTML 全部解析完 → 按序执行
多个脚本的执行顺序不同
如果页面引入多个外部脚本,顺序控制很关键:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 多个 async:谁先下载完谁先执行,**完全不保证声明顺序**,比如 script2.js 比 script1.js 快,就会先运行
- 多个 defer:始终按它们在 HTML 中出现的**书写顺序依次执行**,适合库文件 + 业务代码这种依赖链
适用场景有明确分工
不是“哪个更快就用哪个”,而是看脚本是否需要 DOM、是否相互依赖:
- 用 async:统计代码(如 GA)、广告脚本、埋点 SDK——独立运行、无需操作页面元素
- 用 defer:初始化逻辑、表单验证、轮播组件——要访问 DOM,或依赖前面加载的工具库(如先加载 lodash,再加载业务模块)
- 不用 async/defer:内联脚本(
<script>...</script>)或必须同步执行的配置脚本
一些实际注意事项
这些细节容易被忽略,但会影响行为一致性:
- 两者都只对外部脚本(
src属性存在时)有效,内联脚本加了也没用 - 如果同时写
async defer,浏览器会优先按 async 处理,defer 被忽略 - defer 脚本执行完才会触发
DOMContentLoaded;async 脚本执行不参与该事件的等待队列 - 现代实践中,多数业务 JS 推荐用 defer;第三方无依赖资源(如 analytics.js)用 async 更合理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










