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

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

DOMContentLoaded 在 HTML 解析完成且 defer 脚本执行后触发,load 则等待图片、样式、iframe 等全部子资源加载完毕。监听 DOMContentLoaded 会漏掉图片加载完成。

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

事件触发时机差异

  1. DOMContentLoadedHTML 解析完 + defer 脚本执行后
  2. load所有子资源加载完成后
  3. 图片完成需要通过 load 或 image.onload 确认

不要用 DOMContentLoaded 判断图片已加载

核心回答

先记住这个答案

DOMContentLoaded 在文档被完全解析且所有延迟脚本(defer 和 module 脚本)下载并执行后触发,不等待图片、子框架和 async 脚本。load 事件则等待页面所有资源加载完成,包括图片和 iframe。要检测图片加载完成,应监听 load 事件或使用图片自身的 load 事件。

  • DOMContentLoaded 只等 HTML 解析与 defer 脚本
  • load 等所有子资源(图片、样式、iframe)
  • 监听 DOMContentLoaded 会漏掉图片加载

解析与子资源加载的解耦机制

HTML 解析器自上而下处理文档,遇到同步脚本会阻塞解析,遇到 defer 或 module 脚本则延迟到解析结束后执行。DOMContentLoaded 事件在 HTML 解析完成且这些延迟脚本执行完毕时触发。此时外部图片、iframe 以及 async 脚本可能仍在加载或执行,事件不会等待它们。需要注意的是,defer 和 module 脚本会等待样式表加载完成,因此当页面存在这类脚本时,样式表会在事件触发前完成,事件被间接推迟;但若没有这类脚本,普通样式表不会直接阻塞该事件。

load 事件由浏览器在所有资源加载完成后触发。资源包括 <img>、<link> 引用的样式表、<iframe> 内的文档以及媒体文件。若页面存在慢速图片,监听 load 的脚本将明显晚于 DOMContentLoaded 执行。这是两个事件核心区别,也是选择监听对象时的依据。

统计首屏图片加载完成时间

假设页面有 20 张首屏图片,你想要在所有图片可见后执行曝光统计。若使用 document.addEventListener('DOMContentLoaded', ...),回调触发时图片可能只加载了一部分,统计到的尺寸或自然宽度可能失真。在慢网络下,DOMContentLoaded 可能早于最后一张图片加载完成很长时间,具体差异取决于网络状况和资源大小。

正确做法是监听 window.load,但也要考虑图片加载失败和缓存情况。更精细控制可用 Promise.all 结合每张图片的 complete 属性与 load、error 事件。若只需图片真正解码完成,还需检查 decode() 方法。load 事件已能保证资源下载且可显示,但在慢网络下它可能大幅晚于 DOMContentLoaded,具体差异取决于资源数量和网络状况。

失效条件与动态资源陷阱

DOMContentLoaded 不等待 async 脚本、动态插入的图片或通过 JS 创建的 DOM。如果你在 DOMContentLoaded 回调里动态给 <img> 设置 src,该图片的加载会延迟 load 事件(除非 load 已经触发),因此不能认为不影响 load。若需感知该动态图片的加载完成,应使用图片自身的 load 事件。

iframe 本身也是子资源,会延迟 load 事件。若嵌入慢速第三方 iframe,页面 load 可能被拖后几秒。如果需要尽快执行脚本,应避免监听 load;若需统计真实加载完,可接受延迟并设置超时保护,或用 iframe 的 load 事件单独处理。

回答前,多想一步

容易答错的地方

在 DOMContentLoaded 中读取图片宽度
DOMContentLoaded 时图片可能未加载完成,读取 img.naturalWidth 可能为 0 或未更新。必须等图片自己的 load 事件或 window load。许多新手在此误判,导致懒加载失效。
以为 defer 脚本不等待样式表
MDN 指出,defer 和 module 脚本会等待样式表加载完成,而 DOMContentLoaded 事件在它们执行后触发,因此脚本是否为 defer 类型直接影响事件时机。若页面只有普通同步脚本(非 defer),这些脚本也会等待样式表,但若没有脚本,样式表不阻塞 DOMContentLoaded。常见误区是笼统宣称「样式表会阻塞 DOMContentLoaded」或「样式表不阻塞任何脚本」,实际需区分脚本类型。
试着用自己的话回答

面试官还会怎么问?

如果我的脚本是在 DOMContentLoaded 之后通过 async 方式加载的,如何确保初始化逻辑执行?

检查 document.readyState。若为 'loading',直接监听 DOMContentLoaded;否则立即执行。由于 JS 单线程特性,不存在竞态。这是 MDN 推荐的标准方法。

图片设置了 loading=lazy 是否会影响 load 事件触发?

会。懒加载图片如果不进入视口,就不会触发下载,因此 window.load 可能提前触发而不等待这些图片。只有进入视口的懒加载图片才会被加载,因此 load 事件不保证所有图片加载完。需要结合 IntersectionObserver 自行管理。

DOMContentLoaded 与 document.readyState 的值有什么关系?

DOMContentLoaded 触发前,readyState 会变为 'interactive'(但在执行 defer 脚本之前变为 interactive,defer 执行完后事件触发)。load 触发后变成 'complete'。但本题重点是事件语义,状态值仅是旁证。

从一道题,走向一组知识

把知识连起来

渲染与调度

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

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

渲染与调度

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

同属「渲染与调度」专题,接着看 document.readyState readystatechange 加载状态 在具体场景中的处理方式。

参考资料

  • Document: DOMContentLoaded event

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

本题目录
  1. 先记住这个答案
  2. 解析与子资源加载的解耦机制
  3. 统计首屏图片加载完成时间
  4. 失效条件与动态资源陷阱
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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