CSS硬件加速

Author Avatar
GeniusFunny 2月 20, 2020
  • 在其它设备中阅读本文章

CSS 硬件加速

背景

以前,浏览器渲染页面的内容完全依赖于CPU。

现在,借助功能强大的GPU,我们可以利用这种硬件来实现更好的性能,所以使用GPU来合成网页的内容可以带来非常显著的加速。

使用GPU合成的优点:

  1. 在涉及大量元素的绘制和合成操作时,使用GPU实现要比CPU(在速度和功耗方面)有更好的效率,因为GPU就是为这种场景设计的。
  2. GPU上已有的内容不需要readbacks。
  3. 得益于CPU和GPU之间的并行性,可以同时运行创建高效的图形管道。

基础知识

了解浏览器如何渲染页面的基本构建块有助于理解GPU加速在浏览器是怎么操作的。

image.png

网页的内容被存储在成为DOM树的Node节点上,页面上每个节点都会生成一个DOM节点,但是从DOM树到屏幕上绘制的内容还有很大差异。

Node —> RenderObject

DOM树中的每个Node都有可见性,所有可视的元素对应着一个RenderObject,RenderObject存储在并行树中,RenderObject知道如何在屏幕上绘制节点。GraphicsContext负责将像素写入最终显示在屏幕上的Bitmap。

RenderObject —> RenderLayer

每个RenderObject直接或间接通过祖先RenderObject与RenderLayer相关联。共享相同坐标空间(受同一CSS属性影响)的RenderObject通常属于同一RenderLayer。RenderLayer与我们理解的z-index可以关联起来,主要是用来实现层叠上下文,保证页面元素能按正确的顺序合层。

有许多情况可以触发为特定的RenderObject生成新的RenderLayer:

  1. 根元素
  2. 具有定位
  3. 透明度不为1
  4. 有overflow、filter、mask或reflection
  5. 有CSS transform
RenderLayer —> GraphicsLayer

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

每个GraphicsLayer都有一个GraphicsContext,GraphicsContext负责输出该层的bitmap,bitmap存储在共享内存中,通过纹理(texture)上传到GPU,GPU将多个bitmap进行合成,然后绘制到屏幕上。

RenderLayer必须满足下列条件之一才能拥有自己的合成层

直接原因:

  1. 拥有3D和透视变化属性
  2. video元素
  3. 3D或者硬件加速的2D元素
  4. 硬件加速的插件,比如 flash 等等
  5. 在 DPI 较高的屏幕上,fix 定位的元素会自动地被提升到合成层中。但在 DPI 较低的设备上却并非如此,因为这个渲染层的提升会使得字体渲染方式由子像素变为灰阶
  6. 有3D transform
  7. backface-visibility 为 hidden
  8. 图层具有作为合层图层的后代
  9. 对 opacity、transform、fliter、backdropfilter 应用了 animation 或者 transition(需要是 active 的 animation 或者 transition,当 animation 或者 transition 效果未开始或结束后,提升合成层也会失效)
  10. will-change 设置为 opacity、transform、top、left、bottom、right(其中 top、left 等需要设置明确的定位属性,如 relative 等

总结

优点
  1. 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
  2. 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
  3. 对于 transform 和 opacity 效果,不会触发 layout 和 paint
缺点
  1. 在内存资源有限的设备上,合成层带来的性能改善,可能远远赶不上过多合成层开销给页面性能带来的负面影响
  2. 除了我们显式的声明的合成层,还可能由于重叠原因不经意间产生一些不在预期的合成层,极端一点可能会产生大量的额外合成层,出现层爆炸的现象。

合成器

渲染分为两个阶段,第一阶段是绘制、第二阶段是合成;合成器负责在合成之前将必要的转换应用于每个合成图层的位图,由于层的绘制与合层分离,所以我们仅需绘制需要重新绘制的图层并重新合成。

浏览器每次创建一个新帧的的时候,合成器都会绘制(draw);draw是合成器将layers combine到屏幕上,与paint完全不同。

合成器可以使用GPU执行其draw步骤,在传统的软件渲染模型中,浏览器进程将带有页面内容的Bitmap传递给浏览器进程进行显示。在硬件加速架构中,通过调用特定于平台的3D API,在GPU上合成。渲染器的合成器实质上是使用GPU绘制页面的矩形区域到单个Bitmap中(最终的页面图像)。

image.png

image.png

参考资料

  1. Stick to compositor only properties and manage layer count
  2. Simplify paint complexity and reduce paint areas
  3. Increase Your Site’s Performance with Hardware-Accelerated CSS
  4. 无线性能优化
  5. GPU Accelerated Compositing in Chrome