回流和重绘的理解
摘要:回流(Reflow)和重绘(Repaint)是影响页面性能的关键因素。回流由布局变化触发,会导致重新计算布局;重绘则由样式变化触发,仅重新绘制外观。使用transform实现动画可避免回流,利用GPU加速提升性能,实现60fps流畅动画,相比传统修改top/left等方法更具优势。transform通过修改合成层属性,不阻塞主线程,适合复杂动画场景,但需注意避免滥用导致内存消耗过大。
·
元素在渲染过程中会涉及到性能问题,元素的展示回流和重绘是如何影响的?

回流和重绘
回流 (Reflow)
- 定义:当渲染树(Render Tree)中的一部分或全部因为元素尺寸、布局、隐藏等改变而需要重新构建布局的过程
- 触发条件:
- 页面首次渲染(最核心的回流场景)。
- 添加/删除/移动DOM元素
- 元素尺寸/位置变化(宽高、边距、定位position、display从非none变为none等)
- 窗口大小改变、滚动页面
- 字体大小改变
- 读取offset系列、scroll系列、client系列、getComputedStyle等布局属性(浏览器为获取准确值会强制回流)
为什么在获取属性时也会造成回流,因为浏览器会批量计算页面布局,有可能会无法拿到最新的属性值,所以每次获取都会重新触发回流。
重绘 (Repaint)
- 定义:当元素样式改变但不影响布局时,浏览器重新绘制元素外观的过程
- 触发条件:
- 颜色改变color
- 背景色/背景图改变
- 边框样式改变
- visibility改变
- outline等
关系:回流一定会触发重绘,但重绘不一定会触发回流
为什么推荐使用transform实现动画
在说明这个之前,我们应该来先理解下浏览器渲染的整个过程,涉及到以下步骤:
HTML解析、样式计算、布局、分层、绘制、分块、光栅化、画。而我们所说的transform就是在合成线程中处理,与主线程无关,这就是推荐使用的原因。

优势
-
硬件加速
- 现代浏览器会将transform动画交给GPU处理
- 开启3D变换(如
translate3d)可强制使用GPU加速
-
避免回流
- transform修改的是元素的合成层属性,而合成层属性渲染不会影响渲染主线程
- 动画过程中不会触发回流和重绘,只在合成阶段处理
-
独立图层
- transform动画元素会被提升到独立的合成层
- 避免影响其他元素的渲染
-
更流畅的60fps
- 动画在合成线程执行,不阻塞主线程
- 即使是JavaScript控制的transform动画也比直接修改样式性能更好
transform动画 VS 传统动画对比
| 特性 | transform动画 | 传统动画(修改top/left等) |
|---|---|---|
| 性能 | GPU加速,性能高 | CPU处理,性能较低 |
| 回流 | 不触发回流 | 触发回流,性能开销大 |
| 流畅度 | 60fps流畅动画 | 可能出现卡顿、掉帧 |
| 能耗 | GPU能耗高但时间短 | CPU持续高负载 |
| 适用场景 | 复杂动画、移动端 | 简单状态变化 |
推荐做法
/* 推荐 - 使用transform */
.element {
transition: transform 0.3s ease;
transform: translateX(100px);
}
/* 不推荐 - 修改布局属性 */
.element {
transition: left 0.3s ease;
left: 100px;
}
支持的transform属性
translate()- 位置移动(替代top/left)scale()- 缩放rotate()- 旋转skew()- 倾斜matrix()- 矩阵变换
注意事项
- 使用
will-change: transform;提示浏览器优化 - 避免滥用,过多的合成层会增加内存消耗
- 2D变换比3D变换内存占用更少
- 动画结束后考虑移除transform属性,避免长期占用GPU内存

更多推荐



所有评论(0)