复合图层和渲染图层
# 复合图层和渲染图层
通过硬件加速就可以使渲染图层提升为复合图层
# 渲染图层
渲染图层:是页面普通的文档流。我们虽然可以通过绝对定位,相对定位,浮动定位脱离文档流,但它仍然属于默认复合层(根层叠上下文),共用同一个绘图上下文对象(GraphicsContext)
# 复合图层
复合图层:又称图形层。它会单独分配系统资源,每个复合图层都有一个独立的 GraphicsContext。(当然也会脱离普通文档流,这样一来,不管这个复合图层中怎么变化,也不会影响默认复合层里的回流重绘)
# 复合图层的创建标准
3D 转换:translate3d,translateZ 依此类推;
<video>
,<canvas>
和<iframe>
元件;transform 和 opacity 经由 Element.animate();
transform 和 opacity 经由 СSS 过渡和动画;
有合成层后代同时本身 fixed 定位
will-change;
拥有加速 CSS 过滤器的元素 filter;
元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
# 复合图层的作用?
(为什么硬件加速会使页面流畅):
合成层的位图,会交由 GPU 合成,比 CPU 处理要快(毕竟该硬件专为处理图像运算的工作负载而设计)
当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
对于 transform 和 opacity 效果,不会触发 layout 、layer 和 paint,直接进入合成线程处理
CPU 和 GPU 之间的并行性,可以同时运行以创建高效的图形管道。
# 复合图层的使用注意事项
尽量不要大量使用复合图层,否则由于资源消耗过度,页面反而会变的更卡
层爆炸,由于某些原因可能导致产生大量不在预期内的合成层,虽然有浏览器的层压缩机制,但是也有很多无法进行压缩的情况,这就可能出现层爆炸的现象(简单理解就是,很多不需要提升为合成层的元素因为某些不当操作成为了合成层)。使用 3D 硬件加速提升动画性能时,最好给元素增加一个 z-index 属性,人为干扰复合层的排序,可以有效减少 chrome 创建不必要的复合层,提升渲染性能,移动端优化效果尤为明显。
# 渲染图层(普通图层)以及复合图层区别
# 层叠上下文
拥有层叠上下文属性的元素会生成一个新的层叠上下文对象,每个层叠上下文对象都是一个渲染图层,渲染图层与复合图层是不同的概念,渲染图层更像是一个纯二维的概念,无论其怎么层叠覆盖最终都归依于根层叠上下文。而复合图层则完全脱离根层叠上下文,相当于开辟新的位面。
形成层叠上下文:
文档根元素 ,称为“根层叠上下文”。
position 属性的值不为 static 且 z-index 值不为 auto 或 0
opacity 属性值小于 1 的元素
flex 布局的元素
will-change 值设定任意属性且值为非初始化值
transform 值不为 none
filter 值不为 none
# 层叠上下文特性
- 层叠上下文可以包含在其他层叠上下文中,并且一起组建一个层叠上下文的层级(出现层级关系)
在根层叠上下文中,比如我们给某元素添加 transform:rotate(7deg); 属性,该元素随即形成新的一个 B 层叠上下文,那么根层叠上下文就与 B 层叠上下文就出现了层级关系。
- 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素
两个兄弟 div,其中一个 div 形成了层叠上下文,处理层叠关系的时候这两个 div 是没有联系的,你在你的区域怎么样都不会影响我正常排布,层叠上下文的元素只考虑自己的子元素
每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。
没有创建自己的层叠上下文的元素会被父层叠上下文同化。
层叠顺序:
层叠等级的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。
参考:深入理解 CSS 中的层叠上下文和层叠顺序 (opens new window) 浏览器渲染魔法之合成层 (opens new window)