重绘与回流
####浏览器的重绘与回流的机制
- 频繁触发重绘与回流,会导致UI频繁渲染,降低js的运行性能,所以要对css的性能进行提高
- 当render tree中的一部分因为元素的规模尺寸、布局、隐藏等改变需要重新构建,就是回流。比如。通过减少会触发回流的css的使用,可以对回流进行优化
- 当render-tree中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格。而不影响布局时,就是重绘,比如(background-color)。
- 重绘的时候不一定会回流,但是回流一定会引起重绘。
会触发重绘与回流的css属性
- 针对重构与回流的优化
- css维度
- 图层维度(chrome创建图层的条件)
- 3D透视变换CSS属性
- 使用加速视频解码
- 拥有3D上下文(WEBGL)或者2D(canvas)
- 混合插件
- 对自己的opcaity做css动画或者使用一个动画webkit变换的元素
- 拥有加速CSS过滤器的元素
- 元素有一个包含复合层的后代节点(一个元素拥有一个子元素,这个子元素在自己的层里)
- 元素有一个z-index较低且包含一个复合层的兄弟元素(就是该元素在复合层上面渲染)
- 尽量避免使用触发重绘、回流的css
- 将重绘、回流的范围控制在单独的图层内
- 学会使用谷歌浏览器的performance工具来观察网页的性能
- 在谷歌的开发和工具中的更多工具中可以看到当前页面的layers的布局,以及为什么会有这么多layers的原因
- 谷歌开发者工具中的rendering可以直观的看到当前页面移动之后进行重绘的元素
- 为元素添加-webkit-transform:transition3d(0,0,0)或-webkit-transform:translateZ(0);属性都会开启GPU的硬件加速,应为浏览器认为这是3D变换,会自动为其设置图层,或者使用will-chang:transform也可以完成新建图层的操作
- 具体案例具体分析,不要盲目的使用图层
- 具体的css替换方案
- 使用translate替换top的改变
- 使用opacity替换visibility
- DOM样式不要一条条修改,都定义在一个className中,集中修改
- DOM离线修改,将元素设置为display:none,然后对元素修改100次再显示出来,这样之用重绘一次(元素出现的时候重绘)
- DOM节点的属性千万不要放在循环的变量里(offsetHeight,offsetWidth)每获取一次都会刷新dom的缓存,然后需要重新去回流
- 不要使用table布局,可能一个很小的改动就会造成整个table的重新布局(30行的table,修改最后一行,回流的时间需要1.15ms,使用div的话只需要0.1ms)
- 对gif图使用单独的图层,这样gif图的改变就不会涉及到整个页面的修改了
- 动画实现速度要与网页的渲染速度相均衡,否则css的渲染可能导致阻塞js的加载
- 使用位置变换时,如果使用了3d变换,那么会启用GPU的能力开启硬件加速,代价就是原来的数据从CPU走总线到GPU,如果数据过多,那么传输的损耗也是一个需要权衡的问题
- 以上的优化点都只是理论,一定要针对真实的应用场景来考量,不能乱用
注:使用opacity替代visibity的话,opacity一定要在特定的图层中,否则整个页面都会触发重构、回流,反之则都不会触发。
图层不要用太多,否则浏览器在图层的合成上就要花费很多的时间