web前端优化(4)

重绘与回流

####浏览器的重绘与回流的机制

  • 频繁触发重绘与回流,会导致UI频繁渲染,降低js的运行性能,所以要对css的性能进行提高
  • 当render tree中的一部分因为元素的规模尺寸、布局、隐藏等改变需要重新构建,就是回流。比如。通过减少会触发回流的css的使用,可以对回流进行优化
  • 当render-tree中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格。而不影响布局时,就是重绘,比如(background-color)。
  • 重绘的时候不一定会回流,但是回流一定会引起重绘。
  • 会触发重绘与回流的css属性

    1. 触发页面重布局的属性
      触发页面重布局的css属性

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