回流重绘原理 + table 布局性能分析,前端面试常考点!

112 阅读5分钟

📌 前言

在前端性能优化领域,“回流(Reflow)”和“重绘(Repaint)”这两个词绝对绕不过去。
如果再加上 table 布局的老坑,这些点几乎是前端面试必问。

「table 为什么不推荐做布局?」
「浏览器是怎么从 URL 渲染出页面的?」
「什么是回流?什么是重绘?各自如何触发?」

搞懂这些,页面更丝滑,面试不掉链子!


🏗️ 一个最简单的 table 列式布局示例

来看个很多新手都写过的 table 多列布局👇

<table>
  <tr>
    <td class="sidebar">左侧边栏</td>
    <td class="main">主体内容</td>
    <td class="sidebar">右侧边栏</td>
  </tr>
</table>
table {
  width: 100%;
  border-collapse: collapse;
}
td {
  border: 1px solid #ccc;
  padding: 10px;
}
.sidebar {
  width: 20%;
  background: #f0f0f0;
}
.main {
  width: 60%;
  background: #e0e0e0;
}

看着能跑,但问题多多。


❌ 为什么 table 不推荐做页面布局?

1️⃣ 语义化问题

table 本质是为展示表格数据而生,
用来做页面结构,既不符合语义化,也对 SEO 和可访问性(A11Y)不友好。


2️⃣ 灵活性太差

相对于 flexgridfloat
table 在响应式布局、顺序调换、列数变化上完全没优势,维护起来也别扭。


3️⃣ 性能坑:回流开销大

table 的单元格相互依赖,任何一个单元格大小改变,都可能影响整行甚至整张表格布局。

当表格内容复杂或动态增删时,局部变化会触发大范围回流(Reflow) ,严重拖慢页面性能。


⚙️ 浏览器是怎么渲染页面的?

搞懂回流和重绘,先要弄明白浏览器从 URL 到页面渲染的整个流程👇

✅ 1. 输入 URL,下载资源

  • 浏览器解析域名、建立连接,下载 HTML 字节流。

✅ 2. 解析 HTML

  • 按 UTF-8 编码解析成字符。
  • 词法、语法分析,生成 DOM 节点对象。
  • 最终构建成 DOM 树(Document Object Model)。

✅ 3. 下载 & 解析 CSS

  • HTML 中遇到 <link><style> 等,发起 CSS 请求。
  • 下载字节流,解析成 CSS 文本,词法分析生成规则,最终构建 CSSOM 树(CSS Object Model)。

✅ 4. 生成 Render Tree

  • 浏览器将 DOM 树和 CSSOM 树结合,生成 Render Tree
  • Render Tree 只包含可见节点(display: none 的节点不会出现)。

✅ 5. Layout(回流 Reflow)

  • 浏览器根据 Render Tree 计算每个元素的盒模型、位置和尺寸,生成 布局树(Layout Tree)
  • 这个过程就是回流:只要元素的几何信息改变,就要重新 Layout。

✅ 6. 分层(Layer Tree)

  • 特定属性会触发单独成层,比如:

    • position: fixed(弹窗)
    • z-index(堆叠上下文)
    • transform / opacity / will-change(GPU 加速)
    • animation / transition
  • 独立图层有助于后续合成和动画性能。


✅ 7. Painting(重绘 Repaint)

  • 每个图层被栅格化(Rasterize),绘制成位图。
  • 改变颜色、背景等样式而不改变几何信息,只触发重绘。

✅ 8. Compositing(合成)

  • 所有图层叠加合成,输出到 GPU,显示在屏幕上。

🧩 一图看懂浏览器渲染流程

下面是对应的渲染流程思维导图,方便你快速记忆👇


输入 URL
│
├─► 下载 HTML
│    ├─ 字节流 → 字符(UTF-8)
│    ├─ 解析标签、属性
│    └─ 构建 DOM 树
│
├─► 下载 CSS
│    ├─ 字节流 → CSS 文本
│    ├─ Tokenize、Parse
│    └─ 构建 CSSOM 树
│
├─► DOM + CSSOM → Render Tree
│    ├─ 过滤掉 display: none
│    └─ 渲染可见节点
│
├─► Layout(回流 Reflow)
│    ├─ 计算盒模型
│    ├─ 确定位置、大小
│    └─ 生成 Layout Tree
│
├─► 分层(Layer Tree)
│    ├─ position: fixed
│    ├─ z-index
│    ├─ transform / opacity
│    ├─ animation / will-change
│    └─ GPU 加速单独成层
│
├─► Painting(重绘 Repaint)
│    ├─ 栅格化 Rasterize
│    └─ 绘制成像素 Bitmap
│
└─► Compositing(合成)
     ├─ 所有图层叠加
     └─ 输出到 GPU 显示屏幕

🔍 回流(Reflow)和重绘(Repaint)到底有什么区别?

📌 回流(Reflow)

  • 元素尺寸、位置、盒模型变化时,浏览器会重新计算布局,这个过程叫回流。

  • 典型触发操作:

    • 添加/删除 DOM 节点(appendChildremoveChild
    • 切换 display: none
    • 改变 widthheightmargin
    • 查询 offsetHeightgetBoundingClientRect() 等布局信息
    • 浏览器窗口尺寸变化

🎨 重绘(Repaint)

  • 样式发生变化但不影响几何信息时,只需要重新涂色,触发重绘即可。

  • 典型:

    • 改变 colorbackground-color
    • visibility: hidden(元素仍占位,只隐藏)

⚡ table 布局为什么放大回流代价?

table 的表格单元格是互相关联的:
某个单元格高度变了,整行都要重新计算,甚至整个表都可能重新布局。
对于大型表格来说,局部变化等于牵一发而动全身,高频的回流很容易拖垮页面


🛠️ 性能优化实战要点

✅ 用 flex / grid 替代 table 做列式布局
✅ 动画尽量用 transformopacity,触发独立图层,避免回流
visibility: hidden 不会触发回流,display: none 会,按需选择
✅ 批量操作 DOM,用 DocumentFragment 减少回流次数
✅ 避免频繁读取布局信息(多次触发同步回流)


📌 面试必问点汇总

  • 渲染流程能画出来吗?
  • 回流 vs 重绘的区别?如何触发?
  • 为什么 table 布局性能差?
  • 有哪些实际优化手段?

记住这套思维导图,面试官追问的时候,你有底气说得明明白白!


✅ 小结

  • table 不适合做页面布局,既不灵活,性能也差。
  • 回流比重绘更消耗性能,要尽量避免不必要的回流。
  • 浏览器渲染链路必须吃透,很多性能优化方案本质就是围绕减少回流重绘做文章。

觉得有帮助,点个 👍 收藏一下,别再被回流重绘难住了!