面试

浏览器渲染流程:从 HTML 到屏幕像素,中间到底发生了什么

这篇文章基于旧博客中的“浏览器工作原理”内容重写,重点解释浏览器如何把 HTML 变成最终可见页面,以及 reflow、repaint 和 transform 的关系。

发布于 2026/06/08 更新于 2026/06/08 6 分钟阅读

浏览器渲染流程是一个很典型的面试题。

很多人会记住几个关键词,比如 DOM、CSSOM、布局、重排、重绘,但如果要把整个流程完整讲出来,还是很容易断掉。

这篇文章我想重新梳理一下这个过程,重点不是记术语,而是搞清楚浏览器到底是怎么一步一步把页面画出来的。

先有一个总览

当浏览器收到一份 HTML 文档后,页面并不是瞬间出现的。

中间大致要经过这些阶段:

  1. 解析 HTML
  2. 解析 CSS
  3. 计算样式
  4. 布局
  5. 分层
  6. 绘制
  7. 分块
  8. 光栅化
  9. 合成并显示到屏幕

这些阶段前后衔接,每一步的输出都会成为下一步的输入。

第一步:解析 HTML

浏览器拿到 HTML 后,会开始解析标签结构,并逐步生成 DOM 树。

在这个过程中还会遇到两类关键资源:

CSS

如果遇到外部 CSS,浏览器会下载并解析它,最后形成 CSSOM。

CSS 不会阻塞 HTML 的继续解析,但它会影响后续渲染,因为浏览器需要样式信息来计算元素最终怎么显示。

JavaScript

如果遇到同步脚本,HTML 解析通常会暂停,等脚本下载并执行完之后再继续。

原因很简单:JavaScript 可能会直接修改当前 DOM 结构,如果 DOM 还在一边生成一边被脚本改,就很容易出现状态不一致的问题。

所以从渲染角度看:

  • CSS 更像“可以并行准备的资源”
  • JS 更像“可能打断当前解析流程的任务”

第二步:样式计算

当 DOM 和 CSSOM 准备好后,浏览器会为 DOM 树上的每个节点计算最终样式,也就是 Computed Style。

这一步的意义是:把作者写的 CSS 规则,真正转换成当前节点的最终可用值。

例如:

  • red 可能会变成 rgb(255, 0, 0)
  • em 可能会换算成具体的 px
  • 层叠、继承、默认值会一起参与最终结果计算

这一步结束之后,可以理解为:浏览器已经知道“每个节点该长什么样”。

第三步:布局

知道样式还不够,还得知道元素具体在页面上占多大、放在哪里。

所以接下来浏览器会做布局计算。

布局阶段会确定元素的几何信息,比如:

  • 宽高
  • 位置
  • 相对包含块的偏移

这一步的产物通常叫布局树。

DOM 树和布局树不是一回事

这是一个很重要的点。

并不是 DOM 里的每个节点都会进入布局树。

例如:

  • display: none 的元素没有几何信息,所以不会出现在布局树里
  • 某些伪元素虽然不在 DOM 树中,但有几何信息,可能会进入布局树

所以布局树更像是一棵“真正参与几何计算和页面排版”的树。

第四步:分层

布局完成后,浏览器不会直接把所有东西一次性画完,而是会先决定哪些内容应该放到不同的图层中。

分层的核心目的,是为了提高后续更新效率。

因为如果某一层发生变化,浏览器不一定需要把整个页面都重新处理,只需要重算受影响的那一层。

常见会影响分层的因素包括:

  • 堆叠上下文
  • transform
  • opacity
  • 某些动画效果
  • will-change

第五步:绘制

分层之后,浏览器会为每一个图层生成绘制指令。

你可以把它理解成:浏览器在写一份“绘图说明书”,告诉后续流程这个层里有哪些内容,应该怎么画出来。

这一步还不是最终像素,只是绘制命令。

第六步:分块与光栅化

接下来,浏览器会把图层拆成更小的区域,也就是分块。

为什么要这样做?

因为页面通常很大,没必要每次都把整层一次性处理完。拆成块之后,可以更灵活地优先处理当前视口附近的内容。

然后进入光栅化阶段。

光栅化的本质,是把前面那些绘制指令真正转换成位图像素。

这一步通常会借助 GPU,更适合大规模像素处理。

第七步:合成与显示

当每一层、每一块都准备好之后,合成线程会根据它们的位置信息,把这些位图组合起来,最终交给 GPU 输出到屏幕。

到这里,用户才真正看到页面。

什么是 reflow

reflow 常被翻译成重排,本质上就是重新计算布局。

只要某个改动会影响元素几何信息,就可能触发 reflow,比如:

  • 宽高变化
  • 字体大小变化
  • 定位相关属性变化
  • 元素增删导致文档流变化

reflow 的代价通常比较高,因为它会影响后续很多阶段。

布局一变,后面可能还要重新分层、重新绘制、重新合成。

什么是 repaint

repaint 是重绘。

它不一定会重新布局,但会重新生成绘制结果。

比如只改了颜色、背景、阴影之类的可见样式,几何信息没变,那么通常不会重新布局,但仍然需要重新绘制。

所以:

  • reflow 一定会引起 repaint
  • repaint 不一定会引起 reflow

为什么 transform 的性能通常更好

这是面试里也很常见的追问。

原因不在于 transform 这个属性本身“更高级”,而在于它通常不会影响布局和绘制阶段的核心结果。

很多时候它只会影响最终合成阶段的变换。

也就是说:

  • 不重新算布局
  • 不重新生成整套绘制指令
  • 主要在合成阶段处理

这就是为什么位移、缩放、旋转等动画,通常更推荐使用 transformopacity

面试时可以怎么讲

如果真的在面试里回答这个问题,我会尽量按下面的顺序讲:

  1. 浏览器收到 HTML 后会先解析 DOM,同时准备 CSSOM
  2. 之后做样式计算,得到每个节点的最终样式
  3. 再做布局,得到元素的几何信息
  4. 然后根据布局结果进行分层
  5. 每个层生成绘制指令
  6. 图层再被分块、光栅化
  7. 最后由合成线程和 GPU 把它们绘制到屏幕上
  8. 如果改动影响几何信息会触发 reflow,如果只影响外观通常是 repaint
  9. transform 更高效,是因为很多情况下它主要发生在合成阶段

这样讲,结构会比较完整,也更容易继续接住后面的追问。