你应该要知道的重绘与重排

面试官:谈谈性能优化问题
答:巴拉巴拉以下省略800字…减少重绘和回流
面试官:那简答说说什么是重绘和回流
那么问题来了,什么是重绘和回流

什么是重绘和回流

重绘(Repaint):当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
重排/回流(Reflow):重新生成布局、增删DOM以及修改元素属性(例如:修改元素的宽高、字体大小),浏览器重新渲染部分或全部文档的过程称为回流。

通过两者概念区别明显得知,重排要比重绘的成本大得多,我们应该尽量减少重排操作,减少页面性能消耗。
另外回流必将引起重绘,重绘不一定会引起回流。

哪些操作会导致重绘与重排

引起重绘的操作,修改如下属性时:

  • color
  • border-style
  • border-radius
  • text-decoration
  • box-shadow
  • outline
  • background

引起回流的操作:

  • 页面初始渲染,这是开销最大的一次重排
  • 浏览器窗口大小发生改变
  • 添加/删除可见的DOM元素
  • 元素尺寸或位置发生改变(例如:margin、padding、width、height、font-size)
  • 元素内容发生变化(例如:文字数量、图片大小)
  • 激活CSS伪类(例如使用:hover伪类)
  • 设置style属性的值(通过设置style属性改变结点样式的话,每一次设置都会触发一次回流)
  • 查询某些属性或调用某些计算方法(例如:offsetWidth、offsetHeight)

一些常用且会导致回流的属性和方法:

clientWidthclientHeightclientTopclientLeft
offsetWidthoffsetHeightoffsetTopoffsetLeft
scrollWidthscrollHeightscrollTopscrollLeft
scrollIntoView()scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()

减少重绘和回流

  1. visibility 代替 display:none ,前者引起重绘,后者引起回流
  2. 不要使用table布局,小改动会引发整个table回流
  3. 将多个样式修改放到一个class中或者通过classText一次性修改
1
2
3
4
5
6
7
8
9
10
11
12
//bad
var left = 1;
var top = 1;
el.style.left = left + 'px';
el.style.top = top + 'px';

//good
el.className = 'className1';

//good
el.style.cssText += 'left:'+ left + 'px;top:' + top + 'px;'

  1. 动画效果应用到脱离文档流的元素上

参考资料:
前端面试 第四篇 重绘和重排(回流)
浏览器的回流与重绘 (Reflow & Repaint)


你应该要知道的重绘与重排
https://xypecho.github.io/2023/01/31/你应该要知道的重绘与重排/
作者
很青的青蛙
发布于
2023年1月31日
许可协议