真实面经题目 · 原创解析

CSS 渲染过程是怎样的?

CSS 渲染过程从解析 HTML 和 CSS 开始,浏览器构建 DOM 与 CSSOM,经过级联、继承和选择器匹配计算样式,再生成渲染树,随后执行布局、绘制、栅格化和合成。理解这条链路可以解释为什么 CSS 会阻塞渲染、为什么某些属性触发重排或重绘,以及为什么 transform、opacity 更适合高频动画。

出现于:字节跳动 · 前端

60 秒回答模板

浏览器渲染页面时,会把 HTML 解析成 DOM,把 CSS 解析成 CSSOM。CSSOM 包含选择器、声明、级联优先级、继承和最终样式规则。DOM 和 CSSOM 结合后生成渲染树,渲染树只包含需要渲染的节点,例如 display: none 的节点不会进入渲染树。接着浏览器进行布局,计算每个盒子的大小和位置;再绘制,把边框、背景、文字、阴影等转成绘制指令;之后栅格化成像素,最后由合成线程把不同图层合成到屏幕。CSS 改动如果影响几何信息会触发布局,影响外观会触发绘制,只影响合成属性时可能跳过布局和绘制。

考点 主流程
难度 真实面经高频题
回答目标 讲清机制、边界和追问

深入解析

01

解析资源

浏览器接收 HTML 后会边下载边解析,构建 DOM 树;遇到 CSS 文件或 style 内容时,会解析出 CSSOM。CSSOM 不是简单文本集合,它包含选择器结构、属性声明、媒体查询、优先级和继承信息。由于脚本可能读取计算样式或修改 DOM,CSS 加载与解析会影响后续渲染和脚本执行顺序,这也是 CSS 常被称为渲染阻塞资源的原因。

02

样式计算

样式计算会把 CSS 规则匹配到 DOM 节点上,并按照来源、重要性、选择器优先级、声明顺序、继承和初始值计算每个元素的最终样式。这个阶段会处理 rem、em、百分比、媒体查询、伪类状态等。选择器并不是页面性能的唯一瓶颈,但在非常大的 DOM、频繁样式失效或复杂动态选择器场景中,样式重算成本会变得明显。

03

渲染树和布局

DOM 中并非所有节点都会进入渲染树,例如 script、meta、display: none 的节点不会占据可见布局位置。渲染树形成后,浏览器会执行布局,计算盒模型尺寸、包含块、正常流、定位、浮动、flex、grid、表格、文本换行等结果。布局阶段输出的是每个可渲染盒子的几何信息,是后续绘制和合成的基础。

04

绘制和栅格化

绘制阶段把布局后的元素转成绘制指令,例如先画背景,再画边框、文字、阴影、轮廓等。现代浏览器会把内容划分到不同图层,绘制指令再被栅格化成像素块。绘制成本和阴影、滤镜、渐变、大面积背景、复杂文本、频繁失效区域有关。只改 color 或 background 通常不需要重新布局,但仍可能需要重新绘制相关区域。

05

图层合成

合成阶段会把不同图层按顺序、变换和透明度组合成最终屏幕结果。transform、opacity 等属性在满足条件时可以只更新合成,不重新布局和绘制,因此适合动画。但图层并非越多越好,过多图层会增加内存、纹理上传和合成管理成本。理解合成能帮助判断什么时候使用 will-change,什么时候应该让浏览器自行决策。

易错点

  • 把 CSS 渲染过程简化成 DOM 加 CSS 直接显示,漏掉 CSSOM、样式计算、布局、绘制和合成。
  • 认为所有 CSS 改动都会完整重排重绘,没有区分布局、绘制和合成的失效范围。
  • 忽略 CSS 是渲染阻塞资源,只从 JS 或接口角度解释首屏慢。
  • 滥用 will-change 或强制分层,忽略图层数量增加会带来内存和合成成本。

面试官追问

CSS 为什么会阻塞渲染?

浏览器需要 CSSOM 来确定元素最终样式。如果没有样式信息就提前绘制,后续样式到达会造成闪烁和大量重算。因此外部 CSS 常会阻塞首次渲染,关键 CSS 内联和非关键 CSS 延后加载能改善首屏。

display: none 和 visibility: hidden 在渲染树中有什么区别?

display: none 的元素不进入渲染树,不占据布局空间;visibility: hidden 的元素仍参与布局,只是在绘制时不可见。因此前者通常影响布局,后者通常主要影响绘制可见性。

为什么 transform 动画通常更流畅?

transform 不改变元素在文档流中的布局占位,在满足条件时可以由合成阶段处理,跳过主线程布局和绘制的大部分成本。但如果元素内容复杂或图层过多,仍然可能出现资源压力。

渲染树和 DOM 树是一回事吗?

不是。DOM 表示文档结构,渲染树表示需要参与渲染的可见盒子及其样式。某些 DOM 节点不会进入渲染树,伪元素等视觉盒子也可能出现在渲染结构中。