一、核心区别一句话总结
👉 Reflow(重排) = 改变了布局(几何信息)
👉 Repaint(重绘) = 只改外观,不影响布局
二、什么是 Reflow(重排)
定义:
当 DOM 元素的几何属性发生变化,浏览器需要重新计算布局(位置 + 大小),这个过程叫 重排。
常见触发场景
-
改变元素尺寸
div.style.width = '200px' -
改变位置
div.style.marginLeft = '20px' -
添加 / 删除 DOM
parent.appendChild(child) -
改变字体大小
-
浏览器窗口 resize
-
读取某些属性(会强制重排)
div.offsetWidth
特点
- ❗ 开销大(性能杀手)
- ❗ 会影响其他元素(连锁反应)
- ❗ 一定会触发 repaint
三、什么是 Repaint(重绘)
定义:
当元素的外观发生变化,但不影响布局时,浏览器只需要重新绘制。
常见触发场景
-
改颜色
div.style.color = 'red' -
改背景
div.style.background = 'blue' -
改阴影、透明度
div.style.opacity = 0.5
特点
- ✅ 开销比 reflow 小
- ✅ 不影响布局
- ❗ 只在当前元素生效
四、流程关系(非常重要)
浏览器渲染流程:
DOM -> CSSOM -> Render Tree -> Layout -> Paint
↑ ↑
Reflow Repaint
👉 Reflow 发生在 Layout 阶段
👉 Repaint 发生在 Paint 阶段
五、关系总结(面试重点)
| 对比 | Reflow | Repaint |
|---|---|---|
| 是否影响布局 | ✅ 是 | ❌ 否 |
| 开销 | ❌ 大 | ✅ 小 |
| 是否影响其他元素 | ✅ 会 | ❌ 不会 |
| 是否触发 repaint | ✅ 一定会 | ❌ 不一定触发 reflow |
六、经典面试加分点(优化建议)
1. 减少重排次数
// ❌ 多次操作 DOM
div.style.width = '100px'
div.style.height = '100px'
// ✅ 合并操作
div.style.cssText = 'width:100px;height:100px'
2. 脱离文档流操作
// 使用 display:none
div.style.display = 'none'
// 修改
div.style.width = '200px'
div.style.display = 'block'
3. 使用 DocumentFragment
const frag = document.createDocumentFragment()
4. 避免频繁读取布局信息
// ❌ 读写交替(触发多次 reflow)
div.style.width = '100px'
console.log(div.offsetWidth)
5. 使用 transform 替代 top/left
// ❌ 触发 reflow
div.style.left = '100px'
// ✅ 只触发 repaint(甚至走 GPU)
div.style.transform = 'translateX(100px)'
七、一个形象理解
👉 把页面当成一张纸:
- Reflow = 重新排版(段落、位置全变)
- Repaint = 只是重新上色
八、面试标准回答模板(直接背)
Reflow 是指 DOM 元素的几何属性发生变化,浏览器需要重新计算布局,会影响其他元素,性能开销较大;
Repaint 是指元素样式变化但不影响布局,只进行重绘,性能开销较小;
并且 Reflow 一定会引起 Repaint,但 Repaint 不一定触发 Reflow。