前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库script defer async 执行顺序 DOMContentLoaded
浏览浏览器渲染与调度

script 标签的 defer 与 async 属性在下载时机、执行顺序和相对 DOMContentLoaded 的执行点上有什么区别?

script 的 defer 与 async 都让脚本下载不阻塞 HTML 解析,但执行时机和顺序截然不同:defer 会按文档顺序在 DOMContentLoaded 前执行,async 则是加载完即执行,顺序不定。

前端进阶之旅 · 一题精讲更新于 2026.09.05
浏览器#渲染与调度#异步编程
先看核心答案
理解线索

三种脚本加载模式对比

  1. 普通下载与执行均阻塞 HTML 解析
  2. async下载并行,执行时机不定
  3. defer解析后按序,DOMContentLoaded 前

async 和 defer 一起出现时 async 优先。

核心回答

先记住这个答案

普通 script:下载和执行都会阻塞 HTML 解析。async:下载不阻塞解析,但下载完立即执行,执行时阻塞解析,且多个 async 脚本的执行顺序与加载完成顺序一致,不保证文档顺序。defer:下载不阻塞解析,并在 HTML 解析完成后、DOMContentLoaded 事件前按文档顺序执行。defer 脚本会延迟 DOMContentLoaded 的触发。

  • async 下载完就执行,执行时阻塞解析
  • defer 在解析完成后按顺序执行
  • DOMContentLoaded 会等待 defer 脚本

三种模式的处理机制

普通 script:当解析器遇到带有 src 的 script 标签(无 async/defer/module),会立即发起请求并暂停解析。下载完成后同样阻塞解析执行脚本,执行完毕后才继续解析后续 HTML。这种同步行为保证脚本能访问其之前定义的 DOM,但也让后续内容延迟呈现。

async 脚本在下载阶段并行进行,HTML 解析继续。但下载一旦完成,就会立刻中断解析并执行(除非此时解析已结束)。由于网络速度不同,先加载完的 async 脚本先执行,所以无法保证多个 async 脚本的执行顺序与出现顺序一致。执行期间仍会阻塞解析,只是这段时间取决于脚本运行时长。

defer 脚本也会异步下载,但执行被推迟到 HTML 解析完全结束后、DOMContentLoaded 事件触发之前。多个 defer 脚本会严格按照文档中出现顺序执行,即使先下载完的也等待前序脚本。defer 脚本执行完毕后 DOMContentLoaded 才会触发,因此 DOMContentLoaded 的监听器总能拿到其修改后的 DOM。

电商页面加载统计与广告脚本

页面 head 中有一个需要读取完整 DOM 的埋点脚本 analytics.js,还有两个互相独立的广告脚本 ad1.js、ad2.js,HTML body 很长且含大量图片。目标是尽早解析首屏,同时保证埋点不依赖加载状态。给这两个广告脚本加 async,埋点标签加 defer。这样广告下载不阻塞解析,完成后各自执行,即便广告先加载完,也只会延迟执行时的那一小段时间,首屏关键内容能够更快解析。defer 的 analytics.js 在解析完成后执行,确保能遍历全部 DOM 节点并绑定事件,且一定赶在 DOMContentLoaded 之前。

如果将所有脚本都做成 async,广告脚本可能先于 analytics 执行,此时 DOM 尚未完整,且 ad1 与 ad2 的执行顺序无法保证,可能引发与顺序相关的竞态条件。如果都用 defer,虽然顺序确定,但浏览器无法并行控制执行优先级,某个大脚本可能延迟 DOMContentLoaded。因此选择 async 给无依赖的独立脚本,defer 给需要 DOM 且要求顺序的脚本。

失效条件与代价

defer 脚本本身仍然会阻塞 DOMContentLoaded:下载慢的 defer 脚本会推迟事件,导致用户可能看到内容却无法触发逻辑。如果只关心脚本间顺序而不是整个 DOM,async 提供的顺序不确定性可能在多脚本间产生竞争条件。async 只适用于完全独立的脚本,否则后果是程序行为不可预测。

动态创建的 script 并插入 DOM 时,默认按 async 行为执行;若需按序执行可设置 script.async = false,但不会像 defer 那样推迟到 DOMContentLoaded,只会按插入顺序尽快执行。调试时要注意 async 脚本的执行顺序随下载速度变化,难以复现,必要时需改用 defer 或改用模块 type="module"(其隐式 defer)。

回答前,多想一步

容易答错的地方

认为 async 和 defer 只在下载阶段有区别
关键区别在执行:async 下载完就立即执行,可能阻塞解析且顺序不保证;defer 要等解析完并按文档顺序执行。误以为两者相似会导致脚本顺序依赖错误。
以为 DOMContentLoaded 总是先于 async 执行
如果 async 脚本下载极快,可能在 HTML 解析完成前执行,因此其执行可能在 DOMContentLoaded 之前也可能之后。defer 则必然在 DOMContentLoaded 前执行。
试着用自己的话回答

面试官还会怎么问?

多个 defer 脚本中混入一个 async 脚本,执行顺序会怎样?

async 脚本下载完就执行,不排队,所以可能在 defer 脚本之间突然执行,也可能之后,因此不能假设它相对于 defer 的顺序。多个 defer 仍然按文档序,在解析后执行,async 则不一定。

脚本同时写了 async 和 defer,最后实际行为是什么?

对于普通脚本,async 优先级更高,defer 被忽略。浏览器只把该脚本当 async 处理:下载完立即执行,顺序无关。建议不要同时使用以免误解。

动态创建 script 并设置 src 后,默认是阻塞还是 async?

默认是 async 行为:下载完立刻执行,不保证顺序。若想按顺序加载,需要设置 script.async = false,此时会按插入顺序执行,但都会在下载完成后尽快执行,不等 DOMContentLoaded。

从一道题,走向一组知识

把知识连起来

渲染与调度

DOMContentLoaded 事件与 window 的 load 事件分别等待什么资源,监听哪个会漏掉图片加载完成?

了解 DOMContentLoaded 和 load 的时间和区别,理解 defer 与 async 对生命周期的影响。

渲染与调度

HTML 解析器被脚本阻塞时,浏览器的预加载扫描器为什么还能提前发起资源请求?

解析器阻塞时预加载扫描器仍能预取资源,理解 async 下载不阻塞的根本原因。

参考资料

  • <script> HTML script element

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 三种模式的处理机制
  3. 电商页面加载统计与广告脚本
  4. 失效条件与代价
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑