Appearance
渲染层 renderLayer
每一个DOM都会对应一渲染对象(renderObject),每一个渲染对象在处于不同相同的坐标空间时,就会形成一个RenderLayers渲染层。下面的元素都会生成渲染层。不能开启渲染层的renderObject和其最近一个有渲染层的父节点共享。
- 根元素
- 有明确定位的属性 position不为static
- opacity < 1
- transform 存在
- overflow 不为visible
合成层
对于某些符合条件的渲染层会自动处理成合成层,每一个合成层都有一个独立的GraphicsLayer, 不满足和最近一个拥有图形层的共享。 下面这些条件能开启图形层
- 3D transforms
- video canvas iframe // 即使video没有单独的渲染层,但是video在根元素下,也满足
- will-change 属性
- position:fixed
- 对 opacity、transform、fliter、backdropfilter 应用了 animation 或者 transition
除了显示生成合成层外,还有部分隐式的情况,通过谷歌开发者工具render 和 layers可以看到图层的详细信息
隐式场景会导致合成层过多的情况下,浏览器出自动层压缩,会将能够合并的合成层压缩到一个图形层中
图形层 GraphicsLayer
图形层是最终输出到界面的布局,
合成层的好处
- 合成层是GPU渲染,比较快
- 重绘时只会绘制合成层本身
- transform 和 opacity 不会发出重绘
重绘和回流
回流指的是layer的重新生成,有以下几种情况会导致回流,注意的回流都是对当前的合成层进行,不会影响到其他的
- 首次渲染
- 浏览器窗口改变
- 元素的位置或者尺寸发生变化
- 新增删除可见元素
- 元素内容变换
- 元素的字体大小发生变化
- 激活伪类
- 设置style值 // 尽力改css类
- 查询元素边界大写
重绘是指改变visible,outline,背景色等,不会影响的到元素位置的变化。
我们平常的说的重绘和回流都是针对某一个图形层来说的。 所以优化的思路从两个角度出发。
- 尽可能避免回流操作,比如减少style直接js写值,减少对offset的读取。多个新增删除操作合并等。
- 如果没办法避免回流操作,尽量将回流的范围缩小,比如将改动的元素提升到合成层中,注意的合成层的条件是现有渲染层,合成层是从渲染层中来的。常见的生成合成的操作有transform: translate3D,或者简单粗暴添加will-change
