Posts 硬件加速不是银弹
Post
Cancel

硬件加速不是银弹

积木区发现一个诡异的现象,在一些低端机型上,使用 translate3d 反而更卡?来看看 Composite(合成层) 的细节。

01.jpg

Chrome Rendering

03.png

Web 展示流程

JavaScript => Style => Layout => Paint => Composite

  • JavaScript:我们会使用 JavaScript 来实现一些视觉变化的效果。比如做一个动画或者往页面里添加一些 DOM 元素等。
  • Style:计算样式,这个过程是根据 CSS 选择器,对每个 DOM 元素匹配对应的 CSS 样式。这一步结束之后,就确定了每个 DOM 元素上该应用什么 CSS 样式规则。
  • Layout:布局,上一步确定了每个 DOM 元素的样式规则,这一步就是具体计算每个 DOM 元素最终在屏幕上显示的大小和位置。web 页面中元素的布局是相对的,因此一个元素的布局发生变化,会联动地引发其他元素的布局发生变化。
  • Paint:绘制,本质上就是填充像素的过程。包括绘制文字、颜色、图像、边框和阴影等,也就是一个 DOM 元素所有的可视效果。这个绘制过程是在多个层上完成的。
  • Composite:渲染层合并,对页面中 DOM 元素的绘制是在多个层上进行的。在每个层上完成绘制过程之后,浏览器会将所有层按照合理的顺序合并成一个图层,然后显示在屏幕上。

02.jpg

合成层成因

某些特殊的渲染层会被认为是合成层(Compositing Layers),合成层拥有单独的 GraphicsLayer,而其他不是合成层的渲染层,则和其第一个拥有 GraphicsLayer 父层公用一个。

直接原因

  • 覆盖在 video 元素上的视频控制栏
  • 在 DPI 较高的屏幕上,fix 定位的元素会自动地被提升到合成层中。
  • 有 3D transform
  • backface-visibility 为 hidden
  • animation 或者 transition(效果未开始或结束后,提升合成层会失效)
  • will-change 设置为 opacity、transform、top、left、bottom、right

后代元素原因

  • 有合成层后代同时本身有 transform、opactiy(小于 1)、mask、fliter、reflection 属性
  • 有合成层后代同时本身 overflow 不为 visible
  • 有合成层后代同时本身 fixed 定位

overlap 重叠原因

  • 重叠或者说部分重叠在一个合成层之上
    • filter 效果同合成层重叠
    • transform 变换后同合成层重叠
    • overflow scroll 情况下同合成层重叠
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)

主动提升

提升合成层的最好方式是使用 CSS 的 will-change 属性。will-change 设置为 opacity、transform、top、left、bottom、right 可以将元素提升为合成层。

1
2
3
#target {
  will-change: transform;
}

不支持 will-change 属性的浏览器,目前常用的是使用一个 3D transform 属性来强制提升为合成层。

1
2
3
#target {
  transform: translateZ(0);
}

合成层优点

  • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
  • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
  • 对于 transform 和 opacity 效果,不会触发 layout 和 paint

如果你已经把一个元素放到一个新的合成层里,那么可以使用 Chrome 来确认这么做是否真的改进了渲染性能。别盲目提升合成层,一定要分析其实际性能表现。

合成层管理

在内存资源有限的设备上,合成层带来的性能改善,可能远远赶不上过多合成层开销给页面性能带来的负面影响。

不正确使用硬件加速的后果:https://static.chenng.cn/composite-layers/index.html

使用 3D 硬件加速提升动画性能时,最好给元素增加一个 z-index 属性,人为干扰复合层的排序,可以有效减少 chrome 创建不必要的复合层,提升渲染性能,移动端优化效果尤为明显。

如果受限于视觉需要等因素,其他元素必须要覆盖在合成层之上,那应该尽量避免无法层压缩情况的出现。

大多数人都很喜欢使用 translateZ(0) 来进行所谓的硬件加速,以提升性能,但是性能优化并没有所谓的“银弹”,translateZ(0) 不是,本文列出的优化建议也不是。抛开了对页面的具体分析,任何的性能优化都是站不住脚的,盲目的使用一些优化措施,结果可能会适得其反。因此切实的去分析页面的实际性能表现,不断的改进测试,才是正确的优化途径。

文章参考:

Accelerated Rendering in Chrome

CSS3 硬件加速也有坑!!!

无线性能优化:Composite

This post is licensed under CC BY 4.0 by the author.
Trending Tags
Contents

Trending Tags