合成处理
合成处理是将已绘制的不同图层放在一起,最终在屏幕上渲染出来的过程。在这个环节中,有两个因素可能会影响页面性能:一个是所需合成的图层数量,另一个是实现动画的相关属性。
新增图层
在降低绘制复杂度小节中讲到,可通过将固定区域和动画区域拆分到不同图层上进行绘制,来达到绘制区域最小化的目的。接下来我们就来探讨如何创建新的图层,最佳方式便是使用 CSS 属性 will-change 来创建:
css
.nav-layer {
will-change: transform;
}
该方法在 Chrome、Firefox 及 Opera 上均有效,而对于 Safari 等不支持 will-change 属性的浏览器,则可以使用 3D 变换来强制创建:
css
.new-layer {
transform: translate(0);
}
虽然创建新的图层能够在一定程度上减少绘制区域,但也应当注意不能创建太多的图层,因为每个图层都需要浏览器为其分配内存及管理开销。如果已经将一个元素提升到所创建的新图层上,也最好使用 Chrome 开发者工具中的 Layers 对图层详情进行评估,确定是否真的带来了性能提升,切忌在未经分析评估前就盲目地进行图层创建。
仅与合成相关的动画属性
在了解了渲染过程各部分的功能和作用后,我们知道如果一个动画的实现不经过页面布局和重绘环节,仅在合成处理阶段就能完成,则将会节省大量的性能开销。目前能够符合这一要求的动画属性只有两个:透明度 opacity 和图层变换 transform。它们所能实现的动画效果如表所示,其中用 n 来表示数字。
动画效果 | 实现方式 |
---|---|
位移 | transform: translate(npx, npx); |
缩放 | transform: scale(n); |
旋转 | transform: rotate(ndeg); |
倾斜 | transform: skew(X |
矩阵变换 | transform: matrix(3d)(/* 矩阵变换 */); |
透明度 | opacity: 0...1 |
在使用 opacity 和 transform 实现相应的动画效果时,需要注意动画元素应当位于独立的绘图层上,以避免影响其他绘制区域。这就需要将动画元素提升至一个新的绘图层。