重排(reflow)与 重绘(repaint)
重排(reflow)与 重绘(repaint)
在浏览器页面中,重排(reflow) 和 重绘(repaint) 是两个影响页面性能的重要过程:
- 重排(Reflow):也叫回流,指的是当元素的尺寸、位置或页面结构发生变化时,浏览器重新计算元素的位置和大小,进而重新布局的过程。
- 重绘(Repaint):指的是当元素的外观(如颜色、背景色等)发生变化时,浏览器重新绘制页面的过程。
重排的性能开销通常大于重绘,因为它需要重新计算页面布局,甚至影响整个页面的渲染。
一、触发重排和重绘的常见操作
1. 修改布局属性
- 设置元素的宽、高、边距、边框、填充等属性会导致重排和重绘,因为这些操作直接影响页面的布局结构。
2. 改变元素的位置
- 使用 position、top、left 等 CSS 属性会触发重排。
3. 改变文档结构
- 添加、删除 DOM 元素,或在 DOM 树上移动元素会触发重排和重绘。
4. 获取布局信息
- 访问 offsetWidth、offsetHeight、clientWidth、clientHeight 等属性,或调用 getComputedStyle 会触发浏览器的强制重排,以确保返回最新的布局信息。
5. 改变样式
- 修改颜色、背景色、阴影等不会影响布局的属性,会触发重绘而不会触发重排。
二、减少重排和重绘的技巧
1. 批量操作 DOM
- 避免多次操作 DOM:将多个 DOM 操作合并。例如,先将内容添加到 documentFragment 中,最后一次性插入页面。
- 使用 display: none:在修改样式前将元素隐藏,完成后再显示,这样只会触发一次重排。
2. 缓存布局信息
- 在循环中反复访问布局属性(如 offsetWidth)会导致多次重排。可以先将属性缓存起来,再使用缓存的值。
3. 减少 CSS 样式的修改次数
- 通过修改 className 或 style 属性一次性更改样式,而不是逐一更改。
4. 使用 CSS 动画代替 JavaScript 动画
- CSS 动画在浏览器层面优化更好,可以将动画放在 transform 和 opacity 属性上,因为它们通常只会触发重绘而不会触发重排。
5. 减少对复杂选择器的使用
- 尽量避免使用影响范围广的选择器,如 *、descendant selector 等,浏览器在解析这些选择器时可能会影响性能。
6. 使用 will-change 提示浏览器
- will-change 属性告诉浏览器将要发生的变化,提前进行优化。例如,在一个频繁变化的元素上使用 will-change: transform; 可以避免在动画中触发重排。
7. 合理使用 position 和 float
- 尽量少用 float 布局,更多使用 flex 或 grid 布局,这些布局方式通常对性能更友好。
通过这些方法,可以有效减少浏览器重排和重绘的次数,提高页面性能,提升用户体验。
本文由作者按照 CC BY 4.0 进行授权