如何让CSS动画使用GPU(硬件加速)而不是CPU渲染

rjee0c15  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(359)

在阅读了一篇关于CSS animations and how to build them的文章后,我构建了自己的CSS动画,并试图提高CSS动画的性能,我的动画由三个HTML元素组成,它们改变宽度以指示媒体正在播放。
在ChromeDevtools中检查时间轴和资源选项卡时,我发现动画会导致高CPU负载。
如何将动画转换为GPU硬件加速,而不是浏览器渲染器,这会导致高CPU负载?我读到过您可以使用硬件加速来强制动画在GPU上运行。

  • 有没有办法把这个(动画条的宽度)转换成GPU层?我能翻译一下吗?或者有更好的方法?*

有3个小节。这是它的动画,不是样式。

@keyframes music {
  0%   { width:17px;  }
  10%  { width:11px;  }
  20%  { width:37px;  }
  30%  { width:30px;  }
  40%  { width:15px;  }
  50%  { width:10px;  }
  60%  { width:24px;  }
  70%  { width:17px;  }
  80%  { width:21px;  }
  90%  { width:32px;  }
  100% { width:17px;  }
}
.lines-ani {
    transform: rotateY(180deg);
}
.lines-ani .lines {
    animation: music 1.5s 2s ease-out alternate infinite;
}
.lines-ani .lines:before {
    animation: music 1.5s 1.5s ease-out alternate infinite;
}
.lines-ani .lines:after {
    animation: music 1.5s 2.5s ease-out alternate infinite;
}
kse8i1jr

kse8i1jr1#

如果你想避免重画,并将动画移动到GPU,那么你可以使用3D转换来产生效果,而不是动画width。如this article中所述,使用3D转换意味着浏览器将使动画GPU加速。
CSS动画、转换和过渡不会自动由GPU加速,而是由浏览器较慢的软件渲染引擎执行。那么到底是什么迫使浏览器切换到GPU模式呢?许多浏览器通过特定的CSS规则提供GPU加速。
目前,Chrome、FireFox、Safari、IE9+和最新版本的Opera等浏览器都配备了硬件加速功能;他们只在有迹象表明DOM元素将从中受益时才使用它。对于CSS,最强的迹象是3D转换正在应用于元素。
将动画转换为3D变换本身并不是一个很大的过程,所需要的只是在所有三个元素上设置一个初始的width,并根据设置的初始宽度将@keyframes规则中的width转换为相应的比率值。
一个宽度动画通常就是scaleX,但是我们使用了scale3d,因为我们需要将动画移动到GPU上。由于scale3d有3个参数(用于三个轴中的每一个轴的缩放),我们可以提供1(初始缩放)作为其他两个轴的值。
例如,所提供的10%帧具有width: 11px设置,下面是我们如何获得其等效的scale3d值:

  • 在元素上设置一个初始值或起始值width。在下面的代码片段中,我将其设置为17px。
  • 根据初始宽度和所需宽度得到X轴的缩放比例,即11px/17px(即0.64)。
  • 因此,等效的3D缩放变换将是scale3d(0.64, 1, 1)
@keyframes color-bar {
  0% {
    transform: scale3d(1,1,1);
  }
  10% {
    transform: scale3d(0.64,1,1);
  }
  20% {
    transform: scale3d(2.17,1,1);
  }
  30% {
    transform: scale3d(1.76,1,1);
  }
  40% {
    transform: scale3d(0.88,1,1);
  }
  50% {
    transform: scale3d(0.58,1,1);
  }
  60% {
    transform: scale3d(1.41,1,1);
  }
  70% {
    transform: scale3d(1,1,1);
  }
  80% {
    transform: scale3d(1.23,1,1);
  }
  90% {
    transform: scale3d(1.88,1,1);
  }
  100% {
    transform: scale3d(1,1,1);
  }
}
.lines-ani {
  width: 25vw;
  transform: rotateY(180deg);
}
.lines-ani .lines {
  position: relative;
  width: 17px;
  height: 10px;
  background: red;
  transform-origin: left;
  animation: color-bar 1.5s 2s ease-out alternate infinite;
}
.lines-ani .lines:before {
  position: absolute;
  content: '';
  top: 125%;
  height: 100%;
  width: 100%;
  background: green;
  transform-origin: left;
  animation: color-bar 1.5s 1.5s ease-out alternate infinite;
}
.lines-ani .lines:after {
  position: absolute;
  content: '';
  top: 250%;
  height: 100%;
  width: 100%;
  background: green;
  transform-origin: left;
  animation: color-bar 1.5s 2.5s ease-out alternate infinite;
}
<div class='lines-ani'>
  <div class='lines'>
  </div>
</div>
    • 注:**如果你不想使用scale3d,你也可以使用scaleX() translateZ(0)translateZ(0)是一个3D变换,整个变换仍然会产生相同的效果。

相关问题