重绘(Repaint)、重排 / 回流(Reflow / Layout)
浏览器回流和重绘区别:
回流是元素布局发生变化,浏览器需要重新计算布局,性能开销较大;
重绘是元素外观变化,不影响布局,只需重新绘制,性能较好;
回流一定会触发重绘,而重绘不一定触发回流。
一、先理解浏览器渲染流程
浏览器(如 Google Chrome、Safari)渲染页面流程:
HTML → DOM
CSS → CSSOM
DOM + CSSOM → Render Tree
↓
Layout(回流 / 重排)
↓
Paint(重绘)
↓
Composite(合成)
流程图:
解析HTML
↓
解析CSS
↓
生成Render Tree
↓
回流 (Reflow)
↓
重绘 (Repaint)
↓
合成显示
二、什么是回流 / 重排(Reflow / Layout)
回流(Reflow):
当 元素的几何信息改变 时,浏览器需要重新计算布局
比如:
- 宽度改变
- 高度改变
- 位置改变
- 元素增加删除
- 字体大小改变
都会触发 回流
例如:
div.style.width = "200px"
浏览器必须重新计算:
- 这个元素位置
- 兄弟元素位置
- 父元素高度
所以:
👉 回流非常耗性能
三、什么是重绘(Repaint)
重绘(Repaint):
当 元素外观改变,但布局没变
例如:
div.style.color = "red"
只需要重新绘制颜色:
不需要计算布局
所以:
👉 重绘比回流性能好
四、回流 vs 重绘
| 类型 | 是否计算布局 | 性能 |
|---|---|---|
| 回流(Reflow) | ✅ 需要 | 慢 |
| 重绘(Repaint) | ❌ 不需要 | 较快 |
五、回流一定会触发重绘
这是一个重要知识点:
👉 回流一定会触发重绘
👉 重绘不一定触发回流
关系:
回流 → 重绘
重绘 ≠ 回流
六、哪些操作会触发回流
非常重要(面试常问)
1、DOM结构变化
appendChild
removeChild
2、元素尺寸变化
width
height
margin
padding
3、字体变化
font-size
font-family
4、浏览器窗口变化
window.resize
5、读取布局属性(非常重要)
这些代码会 强制回流
offsetWidth
offsetHeight
clientWidth
getBoundingClientRect()
例如:
div.style.width = "200px"
console.log(div.offsetWidth)
浏览器必须:
- 先回流
- 再返回宽度
这叫:
👉 强制同步回流(性能杀手)
七、性能优化(非常重要)
❌ 错误写法(多次回流)
div.style.width = "100px"
div.style.height = "200px"
div.style.margin = "20px"
会触发多次回流
✅ 正确写法(合并修改)
div.style.cssText = `
width:100px;
height:200px;
margin:20px;
`
只回流一次
八、使用 class 优化
❌
div.style.width = "100px"
div.style.height = "200px"
✅
div.classList.add("active")
九、使用 DocumentFragment(高级优化)
const fragment = document.createDocumentFragment()
for(let i=0;i<100;i++){
const div = document.createElement("div")
fragment.appendChild(div)
}
document.body.appendChild(fragment)
👉 只触发一次回流
十、最强优化:使用 transform(非常重要)
这是一个浏览器渲染机制的问题,本质是:transform 不会改变元素的布局(Layout),只改变元素的绘制(Paint/Composite)
所以不会触发 回流(Reflow),只会触发 重绘(Repaint) 或 合成(Composite)。
这个元素只是视觉上移动了但它在布局中的位置没有变
- 不影响其他元素位置
- 不重新计算布局
- 不触发回流
修改:
left
top
width
height
会触发回流 ❌
推荐:
transform: translate()
scale()
rotate()
例如:
transform: translateX(100px)
👉 不触发回流
👉 只触发合成层
性能最好 🚀
十一、GPU加速(高级知识)
transform: translateZ(0);
或:
will-change: transform;
浏览器(如 Blink 引擎)会开启 GPU 加速:
- 创建合成层
- GPU渲染
性能提升明显
也就是
会开启 GPU 加速(浏览器会:👉 把这个元素 单独交给 GPU 处理)
变成:CPU 计算 → GPU 合成 → 显示
这样动画就会 更流畅

浙公网安备 33010602011771号