浏览器渲染原理,一篇就够了(从输入到像素))

6 阅读5分钟

浏览器幕后 01:从输入到像素(全景图)

本系列名为 《浏览器幕后:渲染流水线深度解构》
第一篇我们先搭好全景图:浏览器从 HTML/CSS 到屏幕像素,到底分了哪几步?每一步解决什么问题?


1. 为啥要学渲染原理?—— 治“无效焦虑”

你已经会写 Flex、Grid、Position,能做出漂亮的页面。但有时候你会遇到这些“玄学”问题:

  • 页面滚动卡顿,明明没几行代码
  • z-index: 9999 就是不生效
  • fixed 元素突然跟着父容器跑了
  • 改一个 width,整个页面闪一下

这些都不是“CSS 的 bug”,而是你不了解浏览器在背后怎么计算
渲染原理就是给你一张“排错地图”:问题出在哪一步,该怎么修,一目了然。


2. 一句话先记住:浏览器把代码变像素,只做 6 件事

步骤英文名大白话
1HTML → DOM读你的 HTML,搭出“元素树”
2CSS → CSSOM读你的 CSS,搭出“样式规则树”
3Style算出每个元素的最终样式(比如 width: 50%200px
4Layout算出每个元素的尺寸和坐标(比如卡片在 x=100, y=200)
5Paint画背景、边框、文字(像画画一样填充像素)
6Composite把多个图层叠在一起,交给屏幕显示

新手先记这 6 步名字即可,后面我会用例子帮你“看”到每一步。


3. 用一个真实卡片,带你“走一遍流程”

假设你有这么一段代码:

<div class="card">Hello</div>
.card {
  width: 50%;
  margin: 0 auto;
  padding: 16px;
  background: #fff;
  border-radius: 8px;
}

浏览器做了这些事:

  1. DOM 树:发现一个 <div>,给它标记为“card”。
  2. CSSOM:找到 .card 规则,记下 width:50%margin:0 auto 等。
  3. 样式计算:父容器宽度 800px → width 最终 = 400px;margin: 0 auto 算出左右 margin 各 200px。
  4. 布局:确定这个 div 的左上角坐标是 (200, 某个 y),宽度 400px,高度由内容+padding 撑开。
  5. 绘制:从 (200, y) 开始画一个白色圆角矩形,里面写黑色文字 “Hello”。
  6. 合成:如果页面还有其他图层(比如固定按钮),按顺序叠好后显示。

你看,一句 width:50% 背后是好几步数学计算。
理解了这些,你就知道为什么“改 width 可能导致整个页面重新布局(重排)”。


4. 你现阶段最该关注哪两步?—— Style 和 Layout

新手遇到的 80% 样式问题,都出在 样式计算布局 阶段:

常见问题归属阶段解决方案方向
优先级混乱(为什么我的样式没生效)Style学习选择器权重
absolute 元素跑飞Layout检查父元素 position: relative
sticky 不生效Layout检查 top 值和父容器 overflow
盒模型总宽度算错Layout确认 box-sizing
fixed 元素相对父容器定位Layout检查祖先是否有 transform

所以:先搞定 Style 和 Layout,你就能解决绝大多数布局痛点。


5. 重排 vs 重绘 —— 性能问题的根源

  • 重排(Reflow):尺寸或位置变了,浏览器要重新计算布局(Layout 阶段)。开销大
  • 重绘(Repaint):外观变了(颜色、背景),但几何不变,只重新绘制(Paint 阶段)。开销小

举例对比

操作触发重排?触发重绘?
width / height
background-color
transform(用 GPU 动画)❌(只走合成)

这就是为什么做动画推荐用 transform 而不是 left


6. 5 分钟实验:亲眼看到重排和重绘的区别

打开 Chrome DevTools → Rendering 面板 → 勾选 Paint flashing(重绘闪烁)。

  • 在页面上快速滚动,你会看到绿色闪烁(重绘)。
  • 写一段脚本每帧改变 left,你会看到 Layout 相关指标飙升。

自己试试:把下面的代码复制到 console 执行,然后看 Performance 面板:

let left = 0;
setInterval(() => {
  document.querySelector('.box').style.left = left++ + 'px';
}, 16);

然后换成 transform: translateX(),对比两者 Layout 耗时。
—— 这个实验能让你一辈子记住“为什么推荐 transform”。


7. 新手阅读这类文章的正确姿势(省力不劝退)

  • 第一遍:只看每节的“结论”和“表格”,别管术语。
  • 第二遍:带着问题“这一步解决了什么?”去读细节。
  • 第三遍:打开 DevTools 做文章里的 5 分钟实验。

判断你是不是真的懂了,不是看你能背出 6 个步骤,而是问自己:

  1. 我的页面卡顿,是重排还是重绘引起的?
  2. 我改的这个属性,会影响 Layout 还是 Paint?
  3. 有没有更便宜的改法(比如 transform 替代 top/left)?

8. 系列预告 & 下次内容

本文是 《浏览器幕后:渲染流水线深度解构》系列的第一篇,后续你会看到:

  • 02 - CSSOM 与样式计算:优先级、继承、值处理
  • 03 - 视觉格式化模型与布局:包含块、BFC、边距折叠
  • 04 - Flex/Grid 的布局算法思维:剩余空间分配、fr 原理
  • 05 - 重排重绘与层叠上下文:性能优化 + z-index 真相

每个概念都会配上“大白话解释”+“可运行的最小示例”。


9. 写在最后:你不是在背概念,而是在建立“排错坐标系”

以前你遇到 fixed 失效,可能会搜一堆文章乱试。
学了渲染原理之后,你会自动想:

  • 它是定位问题 → 先看包含块(有没有 transform 祖先)
  • 它是层级问题 → 看层叠上下文(z-index 生效前提)

这就是“从瞎蒙到推理”的升级。
下一篇,我们正式进入样式计算的世界。


你遇到过最“玄学”的 CSS 问题是啥?评论区写出来,下一篇我可能拿它当案例。