前端进阶之旅前端进阶之旅
  • 基础篇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 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库document.readyState readystatechange 加载状态
浏览浏览器渲染与调度

document.readyState 的 loading、interactive、complete 三个值分别对应页面加载的什么时刻?

readyState 的 loading 表示 HTML 解析未完成,interactive 表示解析结束但子资源未加载完,complete 表示文档及子资源全部加载完成。

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

readyState 映射加载阶段

  1. loadingHTML 解析器仍在工作
  2. interactive解析完成,子资源未完成
  3. complete文档与子资源均已加载

interactive 之后才触发 DOMContentLoaded,complete 后触发 load。

核心回答

先记住这个答案

当 HTML 文档开始下载时,document.readyState 为 loading;HTML 解析器完成解析、DOM 可安全访问,但图片、样式表等子资源仍在加载时变为 interactive,随后 DOMContentLoaded 触发;当所有子资源加载完成后变为 complete,然后 load 事件触发。通过监听 readystatechange 事件,可以在状态切换时执行对应初始化逻辑,作为 DOMContentLoaded 或 load 事件的替代方案。

  • loading:HTML 解析未完,DOM 不可靠。
  • interactive:HTML 解析完,子资源未齐。
  • complete:子资源均完,load 将触发。

状态切换的精确时机

document.readyState 由 HTML 标准规定,反映 HTML 解析器和资源加载的进度。当浏览器开始请求文档时,状态为 loading,此时 document.open() 之后的 HTML 字节流还在被解析,DOM 树尚未闭合,脚本若在此时执行会因节点不完整而可能找不到目标元素,也会阻塞解析进程。一旦解析器遇到 </html> 并完成 DOM 构造,状态立即变为 interactive,表示解析完成但外部资源(如图片、样式表、iframe、带 defer 或 module 的脚本)仍在下载。

从 interactive 到 complete 的转变取决于事件循环中剩余的下载任务。规范要求,当所有子资源(包括延迟脚本和模块脚本)执行完毕,且文档没有尚未完成的加载任务时,状态设为 complete,随后立刻派发 load 事件。需要区分的是:DOMContentLoaded 是在进入 interactive 后、延迟脚本执行完时触发,而 readystatechange 到 interactive 的监听器实际上早于 DOMContentLoaded,因此常被用来在解析完成后、DOMContentLoaded 之前插入非延迟初始化。

在交互状态插入可操作 DOM

假设页面有一个统计脚本,需在 DOM 完整但图片尚未加载时快速读取首屏区域的 DOM 属性。图片通常经过 CDN,可能延迟数秒。若等待 window.onload 则首屏指标被拖慢,若在解析期间执行则节点不存在。工程方案是监听 readystatechange,当状态变为 interactive 时执行测量代码,此时 HTML 已完整解析,所有标签均可访问,且避免等待外部资源阻塞。关键约束是此时样式表可能尚未完全就绪,若需要读取 getComputedStyle 等几何信息,必须确保引用的 CSS 已加载,否则可能得到中间值。

为正确处理,可先检查 document.styleSheets 中关键样式表是否完成加载,或直接依赖标准场景:通常内联脚本在 interactive 前执行,而外部样式表会阻塞脚本执行,故当 readystatechange 到达 interactive 时,执行过的主文档脚本已确保其之前的 CSS 已应用。此例中,测量逻辑放在 readystatechange 回调内,而非 DOMContentLoaded,因为后者在延迟脚本执行后才触发,若测量要求尽量早,则前者更优。最终,代码在 HTML 解析完成瞬间运行,取得稳定 DOM 状态,并将结果上报,图片加载完成与否不影响该数据。

容易失效的假设与兜底

错误假设之一是 interactive 意味着所有脚本(包括 defer 和 module)已经执行。实际上,readystatechange 到 interactive 的时刻出现在文档解析完成后,但 defer 和 module 脚本会在 interactive 之后、DOMContentLoaded 之前按顺序执行,因此此时它们可能尚未运行。同步普通脚本(无 defer/async)会阻塞解析并在解析过程中执行,所以 interactive 时它们已经完成。真正的问题是,如果页面中存在动态插入的脚本或模块,其执行时机可能晚于 interactive,此时 DOM 虽可访问但不代表所有脚本副作用已发生,因此依赖某些库注册的全局对象时可能仍未定义。

另一失效点是,若页面被取消加载(如用户停止导航),readyState 可能停在 interactive 而不进入 complete,这时依赖 complete 做清理工作的逻辑永远不会触发。处理方法是结合 visibilitychange 或 pagehide 事件来兜底。此外,若文档包含同步的 iframe,其加载会影响 complete 的判定,但 interactive 不受影响,因此测量首屏时注意与 iframe 解耦。为可靠,可在 readystatechange 回调中判断 document.readyState 并分支,同时在 window 再监听 load 做最终兜底,代价是少量重复代码,但能覆盖早期状态变化时序不确定的边缘情况。

回答前,多想一步

容易答错的地方

认为 complete 等于 load 触发
正确顺序是 readyState 变为 complete 后,load 事件才触发。它们之间几乎同步,但并非同时,load 事件稍晚。若只监听 readystatechange,内部判断 complete 时可用于替代 load,但若要精确等待 load 事件,应直接监听 load。
在 loading 中操作动态插入脚本
有些开发者误以为在“loading”阶段动态插入脚本会像解析时遇到的 <script> 一样同步执行,实际上通过 DOM 方法插入的脚本默认是异步的,执行点不确定;若使用 document.write 则可能重写文档。更可靠的做法是把初始化代码放在 readystatechange 的 interactive 分支或 DOMContentLoaded 中。
试着用自己的话回答

面试官还会怎么问?

readystatechange 到 interactive 时,defer 脚本执行完了吗?

尚未。defer 和 module 脚本会在进入 interactive 后、触发 DOMContentLoaded 之前按顺序执行,所以当 readystatechange 到 interactive 时,它们还未执行。

为什么用 readystatechange 而不是直接监听 DOMContentLoaded?

readystatechange 到 interactive 早于 DOMContentLoaded,因此在需要更早介入的场景可考虑使用;但日常场景推荐直接监听 DOMContentLoaded,语义更清晰。

readyState 可能从 interactive 回到 loading 吗?

不会,readyState 的变化是单向的:从 loading 到 interactive 再到 complete。重新加载新文档会创建新的 Document 对象,旧对象状态不再变化。

从一道题,走向一组知识

把知识连起来

渲染与调度

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

同属「渲染与调度」专题,接着看 DOMContentLoaded load 事件区别 资源加载 在具体场景中的处理方式。

渲染与调度

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

同属「渲染与调度」专题,接着看 script defer async 执行顺序 DOMContentLoaded 在具体场景中的处理方式。

参考资料

  • Document: readyState property

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

本题目录
  1. 先记住这个答案
  2. 状态切换的精确时机
  3. 在交互状态插入可操作 DOM
  4. 容易失效的假设与兜底
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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