如何开启GPU加速

RenderLayer(负责 DOM 子树),GraphicsLayer(负责 RenderLayer 的子树),其中 GraphicsLayer 层是作为纹理(texture)上传给 GPU 的。
方法:

  • opacity
  • transform
transform:translateZ(0); // 设置这个属性不影响动画

GPU与CPU?

  • GPU
主要做图形处理,渲染顶点,图像变换,吞吐大,运算大,但是对数据流处理能力没有CPU好
  • CPU
对复杂的数据流控制更好

了解页面卡顿的原因

  • 16ms优化
大多数设备刷新频率60HZ(60次/s),每一次刷新耗时16.6ms(1000/60)
所以在浏览器的每一帧画面要在16ms内完成,这样看起来页面才不会卡顿
  • 浏览器的每一帧做什么?
javascript -> style -> layout -> paint -> composite

js: 实现动画,DOM元素的操作
style: 计算DOM应该运用什么css规则
layout: 计算每个DOM的位置和大小,每个DOM位置变化都要reflow
paint: 在多个层上绘制DOM元素的文字,颜色,图像等
composite:渲染层合并,合并图层显示到屏幕上(layer终极)

GPU为什么能加速

关键: 避免layout paint这两个最耗时的步骤,
javascript -> style -> layout -> paint -> composite
javascript -> style -> composite
可以让每一帧画面在16ms内完成,所以看起来不卡顿

60帧最适合人眼交互,低于30fps一下的动画,让人感觉明显变得卡顿

  • 关于不同类型的层
chrome中包含两个层:
渲染层(RenderLayer)
图层(GraphicsLayer,GPU加速触发创建)

怎么触发:
1 3D 或透视变换(perspective、transform) CSS 属性
2 使用加速视频解码的 元素
3 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 元素
4 混合插件(如 Flash)
5 对自己的 opacity 做 CSS 动画或使用一个动画变换的元素
6 拥有加速 CSS 过滤器的元素
7 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
8 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
  • 为什么能避免layout和paint?
开启GPU后,会将经常变换的DOM提升单独的图层(GraphicsLayer),就不会改变自己和周围的DOM布局
 所以每一帧内,浏览器就不用不断的回流,重绘
 只需要第一次布局元素,位图绘入元素,将位图同步到绘制器,加载到GPU内存,然后位图从GPU内存绘制到屏幕上

GPU加速这么好,那么都用GPU加速行不行?

不行,因为GPU不仅要发送渲染图层到GPU,还要存储他们,一边稍后动画中使用
由此,没创建一个新的渲染层,就要消耗内存和复杂的层管理,特别对于移动设备来说,过多的GPU加速会导致页面卡顿合闪退

GPU导致闪退坑

z-index导致创建意外的复合层

A:{
    z-index: 10 //开启的GPU
} 
B:{
    z-index: 15 //没有开启GPU
}

由于B在A上面,所以B会被默认开启GPU,导致额外创建新的合成层,过多会导致手机页面闪退,卡顿

渲染一个网页需要两个线程完成

  • 主线程
  • compositor thread(绘制线程)
未开启GPU加速

GPU加速图像滤波器 gpu加速频率_GPU加速图像滤波器

#### 开启GPU加速

  • GPU擅长
  • 绘制位图到屏幕上
  • 可不断的绘制相同的位图
  • 将同一位图进行位移、旋转、缩放 (就是动画)

优化案列

  • 优化前
@keyframes animation {
  0% {
      top: 10px;
  }
  50% {
      top: 30px;
  }
}
  • 优化后
    通过开启GPU加速,避免layout,paint,让动画更流畅
@keyframes animation {
  0% {
      transform: translateY(10px);
  }

  50% {
      transform: translateY(30px);
  }
}