Skip to content

渲染层 renderLayer

每一个DOM都会对应一渲染对象(renderObject),每一个渲染对象在处于不同相同的坐标空间时,就会形成一个RenderLayers渲染层。下面的元素都会生成渲染层。不能开启渲染层的renderObject和其最近一个有渲染层的父节点共享。

  1. 根元素
  2. 有明确定位的属性 position不为static
  3. opacity < 1
  4. transform 存在
  5. overflow 不为visible

合成层

对于某些符合条件的渲染层会自动处理成合成层,每一个合成层都有一个独立的GraphicsLayer, 不满足和最近一个拥有图形层的共享。 下面这些条件能开启图形层

  1. 3D transforms
  2. video canvas iframe // 即使video没有单独的渲染层,但是video在根元素下,也满足
  3. will-change 属性
  4. position:fixed
  5. 对 opacity、transform、fliter、backdropfilter 应用了 animation 或者 transition

除了显示生成合成层外,还有部分隐式的情况,通过谷歌开发者工具render 和 layers可以看到图层的详细信息

隐式场景会导致合成层过多的情况下,浏览器出自动层压缩,会将能够合并的合成层压缩到一个图形层中

图形层 GraphicsLayer

图形层是最终输出到界面的布局,

合成层的好处

  1. 合成层是GPU渲染,比较快
  2. 重绘时只会绘制合成层本身
  3. transform 和 opacity 不会发出重绘

重绘和回流

回流指的是layer的重新生成,有以下几种情况会导致回流,注意的回流都是对当前的合成层进行,不会影响到其他的

  1. 首次渲染
  2. 浏览器窗口改变
  3. 元素的位置或者尺寸发生变化
  4. 新增删除可见元素
  5. 元素内容变换
  6. 元素的字体大小发生变化
  7. 激活伪类
  8. 设置style值 // 尽力改css类
  9. 查询元素边界大写

重绘是指改变visible,outline,背景色等,不会影响的到元素位置的变化。

我们平常的说的重绘和回流都是针对某一个图形层来说的。 所以优化的思路从两个角度出发。

  1. 尽可能避免回流操作,比如减少style直接js写值,减少对offset的读取。多个新增删除操作合并等。
  2. 如果没办法避免回流操作,尽量将回流的范围缩小,比如将改动的元素提升到合成层中,注意的合成层的条件是现有渲染层,合成层是从渲染层中来的。常见的生成合成的操作有transform: translate3D,或者简单粗暴添加will-change