回流一定会伴随这重绘,但是重绘可以单独发生。
页面渲染过程
- 解析
html
生成DOM
树 - 处理
css
生成cssom
树 - 将
dom
树和cssom
树合并生成render Tree
(渲染树:不包括display:none,head节点,但是包括visibility:hidden的节点) - 根据
render Tree
, 得到每个节点的几何信息(位置与大小:margin,padding,width,height等) - 将上面的到的几何信息传送到
GPU
进行绘制。
回流(reflow) 与 重绘(repaint)
回流(reflow): render Tree 中节点的 大小、边距等发生改变时候需要重新计算几何信息的过程,叫回流
重绘(repaint): 改变元素的字体颜色、背景颜色等 不会影响到页面的布局变化,叫做重绘。
简而言之:
影响页面布局的需要 回流、重绘;
不会改变页面布局的只需要重绘
回流的消耗大(涉及到重新布局,而且一定会伴随这重绘),重绘的消耗小(相对回流)
引起回流的操作
- 页面初始化渲染
- Dom结构改变:删除、插入元素
- 改变节点的几何信息:margin/padding/width/height/display:none/border/fontSize
- 改变窗口的大小(resize)
- 获取某些属性的值(浏览器会为了获得准确的值也会触发回流的过程)
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop/Left/Width/Heigh
- clientTop/Left/Width/Height
- width,height
- 调用了getComputedStyle(), 或者 IE的 currentStyle
减少回流
- 避免逐条样式的改变,这样会频繁触发。最好是一次性改变多条,或者通过 class 实现 (浏览器会对回流做优化,他会等到足够数量的变化发生,在做一次批处理回流)
- 避免循环操作DOM元素,可以先创建一个元素,在这个元素上操作完后再插入页面中
- 读取部分引起回流的属性时可以通过缓存方式将结果保存,尽量不要频繁调用获取。
减少回流的代价
- 将回流的元素设置成绝对定位、固定定位,如此可使得元素脱离文本流,以达到减少代价的目的