回流一定触发重绘,重绘不一定触发回流。重绘开销小,回流代价高。
回流reflow
也叫重排layout
渲染树中部分或全部元素的尺寸、结构或属性变化,浏览器会重新渲染部分或全部文档
触发回流的操作:
·初次渲染
·窗口大小改变(resize事件)
■元素属性、尺寸、位置、内容改变
元素字体大小变化
■
添加或者删除可见dom元素
■激活CSS伪类(如:hover)
■查询某些属性或调用某些方法
clientWidth、clientHeight、clientTop、clientLeft
offsetWidth、offsetHeight、offsetTop、offsetLeft
scrollWidth、scrollHeight、scrollTop、scrollLeft
getComputedStyle()
getBoundingClientRect()
scrollTo()
修改样式的时候,最好避免使用上面列出的属性,他们都会刷新渲染队列。如果要使用它们,最好将值缓存起来。
重绘repaint
某些元素的样式如颜色改变,但不影响其在文档流中的位置,浏览器会对元素重新绘制
不再执行布局阶段,直接进入绘制阶段
合成
利用transform、opacity和filter可实现合成效果,即GPU加速
避开布局分块和绘制阶段
优化
·最小化重绘和重排:样式集中改变,使用添加新样式类名
■使用absolute或fixed使元素脱离文档流(制作复杂动画时对性能有影响)
■开启GPU加速。利用css属性transform opacity will-change等,比如改变元素位置,使用translate会比使用绝对
定位改变其left或top更高效,因为它不会触发重排或重绘,transform使浏览器为元素创建一个GPU图层,这使
得动画元素在一个独立的层中进行谊染,当元素内容没有改变就没必要进行渲染。
·使用visibility替换display:none,因为前者只会引起重绘,后者会引发回流(改变了布局)
。
DOM离线后修改,如:先把DOM设为display:none(有一次Reflow),然后修改再显示,只会触发一次回流
不要把DOM结点属性值放在一个循环当成循环里的变量
不要使用table布局,可能很小的一个小改动会造成整个table重新布局
动画实现速度的选择,动画速度越快,回流次数越多,也可以选择使用requestAnimationFrame
CSS选择符从右往左匹配查找,避免节点层级过多
。
频繁运行的动画变为图层,图层能够阻止该节点回流影响别的元素。比如对于vd©o标签,浏览器会自动将该节
点变为图层
·通过documentFragment创建一个DOM文档片段,在它上面批量操作DOM,完成后再添加到文档中,只触发一
次回流
documentFragment不是真实DOM的一部分,它的变化不会触发DOM树的重新渲染,不会导致性能问题
效果不甚明显,因为现代浏览器会使用队列存储储存多次修改进行优化