什么是重绘和回流

  • 重绘:
    当渲染树中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格,而不会影响布局的操作,比如 border-radius,我们将这样的操作称为重绘。

  • 回流:
    当渲染树中的一部分(或全部)因为元素的规模尺寸、布局、隐藏等改变而需要重新构建的操作,会影响到布局的操作,这样的操作我们称为回流。任何会改变元素几何信息(元素的位置和尺寸大小)的操作,都会触发回流。

    常见引起回流属性和方法:
    (1)添加或者删除可见的 DOM 元素
    (2)元素尺寸改变——边距、填充、边框、宽度和高度
    (3)内容变化,比如用户在 input 框中输入文字
    (4)浏览器窗口尺寸改变——resize事件发生时
    (5)计算 offsetWidthoffsetHeight 属性
    (6)设置 style 属性的值
    (7)修改网页的默认字体时

    回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。

常见的会引起重绘或回流的方法和属性

常见引起重绘属性和方法:

1
2
3
4
5
6
7
8
color
border-style
border-radius
visibility
opacity
background(image, position, repeat, size)
box-shadow
......

常见引起回流属性和方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
css:
width
height
margin
padding
display
border
position
clientWidth(clientHeight, clientTop, clientLeft)
offsetWidth(offsetHeight, offsetTop, offsetLeft)
scrollWidth(scrollHeight, scrollTop, scrollLeft)
......

js:
scrollTo()
getComputedStyle()
getBoundingClientRect()
......

如何减少回流

  1. 使用 transform 替代 top
  2. 不要把节点的属性值放在一个循环里当成循环里的变量;
  3. 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局;
  4. DOM 离线后修改。如:使用 documentFragment 对象在内存里操作 DOM
  5. 不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 cssclass,然后修改 DOMclassName