defer保证顺序且dom解析完执行,async不保序且下载完立即执行;两者均异步下载不阻塞html解析,但执行时机和顺序保障截然不同。

defer 和 async 都不阻塞 HTML 解析,但执行时机完全不同
两者都会让 <script src="..."></script> 下载过程异步化,避免卡住 DOM 构建;但关键差异在「什么时候执行」和「按什么顺序执行」。
常见错误现象:document.getElementById("app") 返回 null,或 jQuery 插件报 $ is not defined —— 很可能是因为脚本在 DOM 尚未就绪、或依赖脚本还没加载完时就执行了。
-
defer:下载并行,执行严格排队,等整个 HTML 解析完、DOMContentLoaded前统一执行 -
async:下载并行,执行不排队,哪个先下完哪个立刻中断 HTML 解析去执行 - 没加任何属性的
<script src="..."></script>:会同步阻塞 HTML 解析,应杜绝
什么时候必须用 defer?
当你写的脚本要访问或修改页面元素,或者多个脚本之间有依赖关系(比如先加载 lodash.js,再加载用到它的 utils.js),就得选 defer。
使用场景举例:
- 初始化导航菜单、绑定按钮点击事件
- 调用
document.querySelector或addEventListener - 多个外部脚本按顺序加载(如
jquery.js→bootstrap.js)
注意:defer 只对带 src 的外部脚本生效;内联脚本写 <script defer>console.log("hi")</script> 会被浏览器忽略。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
async 更适合哪些脚本?
async 是为真正独立、无 DOM 依赖、也不被其他脚本依赖的脚本准备的 —— 比如统计埋点、广告 SDK、错误监控。
典型表现:
- 脚本内部只调用
navigator.sendBeacon或fetch上报数据 - 不读取
document.body,不绑定任何事件,不操作任何节点 - 执行失败不影响主逻辑,且不依赖其他 JS 文件
性能影响明显:如果一个 async 脚本体积大、执行慢,它会在下载完瞬间打断 HTML 解析,拖慢首屏渲染。所以别把 main.js 设成 async。
容易被忽略的兼容性与实操细节
现代浏览器(Chrome 80+、Firefox 69+、Safari 15.4+、Edge 88+)都完整支持 defer 和 async,但仍有几个硬约束常被忽视:
-
defer和async不能共存,浏览器会按规范优先处理async - IE10 及以下不支持
async,defer在 IE4–IE7 行为异常,IE8+ 才符合标准 -
document.write在defer/async脚本中直接报错,禁用 - 想监听加载完成?用
script.onload,不是DOMContentLoaded
最常漏掉的一点:即使加了 defer,如果脚本里用了 import() 动态导入,后续模块的加载和执行仍不受 defer 约束 —— 这部分得靠代码逻辑自己兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










