一句话回答
DOMContentLoaded 是浏览器事件:初始 HTML 文档解析完成、延迟脚本执行完毕时触发,不等图片、iframe 等子资源;子资源全部完成要到更晚的 load 事件。
什么是 DOMContentLoaded?
DOMContentLoaded 是一个浏览器事件:HTML 文档解析完成、DOM 树建好、所有延迟脚本(defer)都执行完之后触发。它不等图片、不阻塞脚本的样式表、iframe 等子资源加载完;那个更晚的时间点是 load 事件。
在性能工具里,它常被缩写为 DCL,在网络瀑布图上是一条标记线,或者在导航计时里叫「DOMContentLoaded 时间」。
DOMContentLoaded、load 和以用户为中心的指标
| 节点 | 什么时候触发 | 说明了什么 |
|---|---|---|
| 首字节时间 | HTML 的头一个字节到达 | 服务器和网络的速度 |
| 首次内容绘制 | 头一段文字或图片绘制出来 | 用户什么时候开始看到东西 |
| DOMContentLoaded | HTML 解析完,延迟脚本执行完 | 代码什么时候可以安全操作 DOM |
| 最大内容绘制 | 最大的可见元素绘制出来 | 主要内容什么时候出现 |
| load | 所有子资源(图片、iframe)加载完 | 页面什么时候完全加载 |
DOMContentLoaded 是给开发者看的技术节点,不衡量用户体验。页面可能很早就触发 DCL,而首屏大图还在加载;也可能因为解析时跑了一个很重的脚本而 DCL 很晚,尽管内容早就看得见了。
从导航计时里读出它
一次页面加载的示例值,来自 performance.getEntriesByType("navigation")[0]:
| 字段 | 值(距导航开始的毫秒数) |
|---|---|
| responseStart(首字节) | 180 |
| responseEnd | 260 |
| domInteractive | 820 |
| domContentLoadedEventStart | 1,140 |
| domContentLoadedEventEnd | 1,165 |
| domComplete | 2,480 |
| loadEventEnd | 2,500 |
domInteractive(820 毫秒,解析完成)到 domContentLoadedEventStart(1,140 毫秒)之间的 320 毫秒,花在执行延迟脚本上;到 domComplete(2,480 毫秒)之间主要是图片等资源。DCL 事件处理时间(End − Start,这里 25 毫秒)长,说明挂在这个事件上的代码在做大量工作。
什么会推迟 DOMContentLoaded
- 阻塞解析的脚本。 head 里普通的
<script src>会停下解析,直到下载并执行完。 - 脚本前面的样式表。 样式表后面的脚本要等这个 CSS,因为脚本可能读取样式。
- 延迟脚本。
defer脚本在 DCL 之前执行,打包体积大就会推迟它。 - HTML 太大。 文档巨大或 DOM 嵌套很深,解析更久。
- 服务器响应慢,后面所有环节都跟着推迟。
async 脚本不阻塞解析,可能在 DCL 之前或之后执行;type="module" 脚本默认就是延迟执行。
在代码里使用这个事件
function init() {
// 这里可以安全地查询和修改 DOM
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init(); // DOM 已经解析完
}
先检查 readyState 很重要:如果你的脚本在事件触发之后才加载,只加监听器永远不会执行。统计脚本常用这个写法,DOM 一就绪就发送首次浏览。
怎么改进
- 不需要在解析期间运行的脚本,加上
defer或async。 - 拆分并缩小 JavaScript 包,把非关键工作挪到 load 之后。
- 内联关键 CSS,其余样式用不阻塞的方式加载。
- 减小 DOM 规模,避免大段内联脚本。
- 加快服务器响应,使用 CDN。
在 TapCub 里
TapCub 的性能报表基于真实访问,把每次加载拆成后端(首字节时间)、网络传输和前端渲染(从响应结束到文档完成),同时给出 P75、P95 的核心网页指标。它不单独报告 DOMContentLoaded;前端渲染涵盖了同样的解析和脚本工作,外加子资源。TapCub 脚本自己只在页面仍在加载时等待 DOMContentLoaded,然后记录浏览。见页面加载多快算好和核心网页指标。
参考资料
- MDN Web Docs. Document: DOMContentLoaded event.
- WHATWG. HTML Living Standard: the end (parsing).
- Harry Roberts (2023). In defence of DOMContentLoaded.
这个解释清楚吗?
我们会根据反馈修改和补充这篇内容。
提交没有成功,请稍后再试。
谢谢你的反馈,我们会据此改进这篇内容。你已经反馈过这篇了,谢谢。
