核心概念
┌──────────┬────────────────────────────┬────────────────────────────┐
│ │ 回流(Reflow) │ 重绘(Repaint) │
├──────────┼────────────────────────────┼────────────────────────────┤
│ 触发 │ 几何属性变化(宽高、位置) │ 外观属性变化(颜色、背景) │
├──────────┼────────────────────────────┼────────────────────────────┤
│ 流程 │ Layout → Paint → Composite │ Paint → Composite │
├──────────┼────────────────────────────┼────────────────────────────┤
│ 性能代价 │ 高 │ 中 │
├──────────┼────────────────────────────┼────────────────────────────┤
│ 包含关系 │ 必定引起重绘 │ 不一定引起回流 │
└──────────┴────────────────────────────┴────────────────────────────┘
---
性能排序
合成(Composite)< 重绘(Repaint)< 回流(Reflow)
---
查看分析
查看网页重绘(Repaint)和回流(Reflow)
方法 1:Chrome DevTools - Rendering 面板(最直观)
1. 打开 DevTools(F12 或 Cmd+Option+I)
2. 右上角三点 → More tools → Rendering
3. 勾选以下选项:
┌──────────────────────┬────────────────────────────┐
│ 选项 │ 作用 │
├──────────────────────┼────────────────────────────┤
│ Paint flashing │ 绿色高亮显示发生重绘的区域 │
├──────────────────────┼────────────────────────────┤
│ Layout Shift Regions │ 蓝色高亮显示发生回流的区域 │
└──────────────────────┴────────────────────────────┘
---
方法 2:Performance 面板(精确分析)
1. DevTools → Performance 标签
2. 点击录制 → 操作页面 → 停止
3. 在火焰图中查找:
- Layout = 回流(紫色)
- Paint = 重绘(绿色)
- Composite = 合成层
点击具体的 Layout/Paint 事件可看到触发原因和耗时。
---
方法 3:Console 监听强制回流
const height = element.offsetHeight
---
方法 4:Layers 面板(查看合成层)
DevTools → More tools → Layers
可以看到哪些元素被提升为独立合成层(will-change、transform 等),合成层内的变化只触发 Composite,不触发重绘/回流。
---
快速判断规则
修改几何属性(宽高/位置/margin)→ 回流 + 重绘(最贵)
修改外观属性(颜色/背景) → 只重绘
修改 transform/opacity → 只合成(最便宜)
解决方案
浏览器渲染流程
DOM + CSSOM → Layout(布局)→ Paint(绘制)→ Composite(合成)
---
回流(Reflow)
触发条件:改变了元素的几何属性,需要重新计算布局
width / height / margin / padding
position / top / left
font-size / display
添加/删除 DOM 节点
执行步骤:Layout → Paint → Composite(三步全走)
---
重绘(Repaint)
触发条件:外观改变,但不影响布局
color / background-color
border-color / box-shadow
visibility / outline
执行步骤:Paint → Composite(跳过 Layout)
---
哪个更影响性能?
回流 >> 重绘
┌──────────┬───────────────────────────────┬──────────────────────┐
│ │ 回流 │ 重绘 │
├──────────┼───────────────────────────────┼──────────────────────┤
│ 代价 │ 高(重新计算整个/局部布局树) │ 中(只重新像素填充) │
├──────────┼───────────────────────────────┼──────────────────────┤
│ 影响范围 │ 可能影响整个页面 │ 仅影响自身区域 │
├──────────┼───────────────────────────────┼──────────────────────┤
│ 包含关系 │ 回流必定引起重绘 │ 重绘不一定回流 │
└──────────┴───────────────────────────────┴──────────────────────┘
---
最优解:只触发合成
transform: translateX(100px);
left: 100px;
opacity: 0;
visibility: hidden;
transform 和 opacity 的动画由 GPU 处理,完全绕过 Layout 和 Paint,性能最好。