async与defer本质区别在于执行时机:async下载完立即执行且不保证顺序,可能阻塞DOM解析;defer则等DOM解析完按序执行。

async 和 defer 的本质区别在哪
关键看脚本执行时机与 DOM 解析是否阻塞。async 是“下载不阻塞、执行也不保证顺序、一下载完就立刻执行”;defer 是“下载不阻塞、执行等 DOM 解析完、按书写顺序执行”。两者都让 不阻塞 HTML 解析,但后续行为完全不同。
怎么一眼判断页面用了 async 还是 defer
打开浏览器开发者工具 → Elements 面板 → 找到 标签 → 直接看属性是否存在:
- 有
async=""或async(布尔属性,值可省略)→ 异步加载 + 立即执行 - 有
defer→ 延迟执行,等待 DOMContentLoaded - 两个都没 → 同步阻塞加载,按顺序下载并执行
注意:async 和 defer 不能共存,浏览器会忽略 defer(若同时存在,以 async 为准)。
async 和 defer 在实际加载过程中的表现差异
用 Network 面板和 Performance 面板能直观验证:
立即学习“前端免费学习笔记(深入)”;
-
async脚本:在 HTML 解析过程中并行下载,一旦下载完成,立刻中断当前解析、执行脚本(可能 DOM 还没解析完),执行完再继续解析 -
defer脚本:并行下载,但执行被推迟到DOMContentLoaded事件前,且多个defer脚本严格按出现顺序执行 - 错误场景:给内联脚本(无
src)加async或defer无效,浏览器会忽略这两个属性
为什么 defer 更适合操作 DOM 的脚本
因为 defer 保证脚本执行时 document 已完全解析(至少是 DOM Tree 构建完成),无需监听 DOMContentLoaded。而 async 脚本执行时机不可控,很可能 document.getElementById 返回 null。
- 典型踩坑:
async加载的初始化脚本里直接查document.body→ 报错或未定义 - 兼容性提醒:
defer在 IE9+、所有现代浏览器都支持;async从 IE10 开始支持,IE9 及以下会退化为同步加载 - 性能建议:第三方分析脚本(如 GA、Sentry)适合用
async;站点核心逻辑(如菜单初始化、表单绑定)优先用defer
真正容易被忽略的是:即使用了 defer,如果脚本依赖另一个尚未加载完成的模块(比如没用 ES 模块 import 或没配好 crossorigin),仍可能因资源加载失败导致执行中断 —— 属性只管加载策略,不管依赖完整性。











