前端性能优化 - 回流和重绘 | 青训营
什么是回流和重绘
回流(重排):元素的位置发⽣变动时发⽣回流。此时在关键渲染路径中的 Layout 阶段,计算每⼀个 元素在设备视⼝内的确切位置和⼤⼩。当⼀个元素位置发⽣变化时,其⽗元素及其后边的元素位置 都可能发⽣变化,代价极⾼。
重绘: 元素的样式发⽣变动,但是位置没有改变。此时在关键渲染路径中的 Paint 阶段,将渲染树中的每 个节点转换成屏幕上的实际像素,这⼀步通常称为绘制或栅格化 另外,重排必定会造成重绘。
如何避免回流和重绘
- 避免频繁操作样式属性:修改元素的样式属性会触发回流。因此,尽量避免在循环或动画中频繁地修改元素的样式属性。可以考虑使用CSS类名一次性修改多个样式属性,或者使用
transform和opacity等属性进行动画效果。
- 使用文档片段进行批量操作:如果需要向DOM中添加多个元素,最好先创建一个文档片段,并将所有元素添加到文档片段中,然后再将整个文档片段一次性地添加到DOM中。这样可以减少回流的次数。
- 缓存布局信息:获取元素的布局信息(如
offsetWidth、offsetHeight、getBoundingClientRect()等)会引起回流。为了避免频繁获取布局信息,可以将这些信息缓存起来,在需要时直接使用缓存的值,而不是重新计算。
- 避免强制同步布局:某些操作(如获取布局信息、使用
offsetTop、offsetLeft等属性)会触发强制同步布局,并导致回流。为了避免这种情况,可以考虑将这些操作延迟执行,或者使用requestAnimationFrame()方法在下一帧中执行。
- 动态插入样式:在DOM加载完成后,动态插入样式比直接修改元素的行内样式更高效。可以通过添加或标签,或者使用JavaScript创建并插入样式节点来实现。