深入理解html 加载、解析、渲染和 DOMContentLoaded、onload事件

一、前言

前端开发中,我们经常会听到这些词:加载(Loading)解析(Parsing)渲染(Rendering) ,以及两个重要的事件:DOMContentLoadedonload

它们看似接近,却分别属于浏览器渲染流程中的不同阶段。

如果不能真正理解这几个概念,就很容易在性能优化、事件绑定、懒加载等场景中产生误区。

本文将带你从浏览器渲染原理出发,彻底理清这些概念的本质与顺序。


二、HTML 从加载到渲染的整体流程

当浏览器开始加载一个网页时,大致会经历以下几个阶段:

  1. 加载资源(Loading)

    浏览器根据 HTML 中的内容,请求并下载 HTML 文件本身,以及其中引用的 CSS、JS、图片、字体等资源。

  2. 解析结构(Parsing)

    浏览器开始自上而下地解析 HTML 文本,构建 DOM 树(Document Object Model)

    同时,遇到 CSS 文件则下载并解析,生成 CSSOM 树(CSS Object Model)

    DOM 与 CSSOM 合并后,形成用于渲染的 Render Tree(渲染树)

  3. 布局与绘制(Layout & Paint)

    渲染树确定每个元素在页面中的几何位置与大小(布局),再将其绘制到屏幕上(绘制)。

  4. 复合与渲染(Composite & Render)

    浏览器将各图层进行合成、优化,并最终显示给用户。

整个过程并不是线性的"等待全部加载完再渲染",而是边解析边渲染 的流式执行。

这意味着:浏览器一旦解析到可绘制的内容(如文字或结构),就会立即开始渲染首屏。


三、加载(Loading)

"加载"指的是浏览器从网络请求并获取资源的过程

包括:

  • 主 HTML 文档的下载;

  • HTML 中引用的 CSS、JS、图片、字体等静态资源的下载。

加载并不代表内容被展示,也不代表资源已经生效。

例如,一个 JS 文件可能早已下载完毕,但由于带有 deferasync,尚未执行。

一个 CSS 文件可能下载完成,但还未解析成 CSSOM,也就还不能影响布局。


四、解析(Parsing)

"解析"是浏览器将文本内容转换为结构化数据的过程。

这一步可以分为两部分:

  1. 解析 HTML → 构建 DOM 树

    浏览器读取 HTML 文本,从 <html> 开始逐行扫描并生成节点。

    但如果遇到 <script> 标签(尤其是没有 asyncdefer 的情况),会暂停 DOM 解析,先执行脚本,再继续。

  2. 解析 CSS → 构建 CSSOM 树

    浏览器下载并解析所有外部样式与内联样式,构建出样式规则树。

    注意:CSSOM 构建完成之前,页面无法完成渲染,因为样式信息尚不完整。

解析阶段是"结构理解"的过程。

只有当 DOM 和 CSSOM 都构建完毕,浏览器才具备完整的页面信息。


五、渲染(Rendering)

"渲染"是浏览器根据 DOM 和 CSSOM 生成视觉结果的过程。

主要包含三步:

  1. 构建渲染树(Render Tree)

    将可见元素(例如非 display:none 的节点)组合起来。

  2. 布局(Layout)

    确定每个元素的大小与位置。

  3. 绘制(Paint)

    将像素渲染到屏幕上。

这就是用户真正"看到页面"的时刻。

首次绘制(First Paint, FP)最大内容绘制(LCP),都是衡量渲染阶段性能的关键指标。


六、DOMContentLoaded 与 onload 的区别

理解这两个事件,就要看浏览器在哪个阶段触发它们。

事件 触发时机 是否等待样式 是否等待图片等资源 是否等待 defer 脚本
DOMContentLoaded DOM 树构建完成后 ✅ 需要等待 CSS 解析 ❌ 不等待图片、iframe 等 ✅ 等待所有 defer 脚本执行
load(onload) 页面及其所有资源加载完成后 ✅ 包括图片、CSS、字体、iframe 等

总结一句话:

  • DOMContentLoaded 表示"文档结构准备就绪";

  • onload 表示"页面完全加载完成"。

所以如果你想在DOM 可用但资源未加载完成时 执行初始化逻辑(如挂载事件),用 DOMContentLoaded 更合适。

如果你需要依赖图片、CSS 等资源(如轮播图尺寸计算),则用 window.onload

移除全局 Loading 通常放在 window.onload 事件里,确保:

  • HTML 文档已经解析完毕;

  • 所有 CSS、图片、字体、iframe 等资源已经加载完成;

  • 页面完整可见,用户体验最佳。

ocument.addEventListener('click', handler) 通常用于全局点击事件委托,比如:

  • 阻止冒泡或处理模态框关闭;

  • 页面统计点击事件(埋点);

  • 菜单、下拉框等交互。

为什么可以放在 DOMContentLoaded

  • DOMContentLoaded 触发时,DOM 树已经构建完毕,也就是说页面上的大部分元素都存在于 DOM 中;

  • 绑定全局事件时,不需要等待图片或其他资源加载完成;

  • 可以保证交互逻辑在用户可以操作页面时尽早生效。


七、顺序与事件时间线

以一个典型页面为例,时间线大致如下:

复制代码
HTML 加载开始
↓
HTML 解析 → 构建 DOM
↓(遇到外部样式)下载并解析 CSS
↓(遇到 <script>)执行 JS(可能阻塞)
↓
DOM 完成 → 触发 DOMContentLoaded
↓
等待所有资源加载完毕(图片、iframe、字体等)
↓
触发 window.onload
↓
后续用户交互与渲染更新(Reflow / Repaint)

八、总结

概念 作用 特点
加载(Loading) 下载 HTML 与资源 仅表示"已获取",未必生效
解析(Parsing) 构建 DOM 与 CSSOM 结构化阶段,JS 可能阻塞
渲染(Rendering) 将内容绘制到屏幕 依赖 DOM + CSSOM
DOMContentLoaded DOM 树构建完毕触发 不等图片,但等 defer 脚本
onload 所有资源加载完毕触发 页面完全就绪

掌握这些阶段的区别,是理解浏览器工作机制的基础。

无论是优化首屏渲染、监控性能指标,还是正确绑定初始化逻辑,理解"加载---解析---渲染"的边界,都是前端进阶的必经之路。

相关推荐
JIngJaneIL2 小时前
就业|高校就业|基于ssm+vue的高校就业信息系统的设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·高校就业
G***T6912 小时前
前端构建工具环境变量,安全管理
前端
武子康2 小时前
Java-174 FastFDS 从单机到分布式文件存储:实战与架构取舍
java·大数据·分布式·性能优化·系统架构·dfs·fastdfs
Want5953 小时前
HTML礼物圣诞树
前端·html
REDcker3 小时前
Cursor Chrome DevTools MCP 配置指南 for Windows
前端·windows·chrome devtools
张可爱3 小时前
20251115复盘记录:让分页乖乖“坐好”+ 卡片统一渐变描边与圆角
前端
Cache技术分享3 小时前
241. Java 集合 - 使用 Collections 工厂类处理集合
前端·后端
Lear3 小时前
解决Flex布局中overflow:hidden失效
前端
Heo3 小时前
原型理解从入门到精通
前端·javascript·后端