为啥我的 CSS 动画会消耗这么多资源?

Posted

技术标签:

【中文标题】为啥我的 CSS 动画会消耗这么多资源?【英文标题】:Why are my CSS animations consuming so many resources?为什么我的 CSS 动画会消耗这么多资源? 【发布时间】:2021-09-03 22:21:28 【问题描述】:

我意识到带有关键帧的 CSS 动画真的很需要资源。

我已经消除了阴影,这在我的例子中提高了近 50% 的性能。我还听说我应该包含一个rotateZ(360deg) 来欺骗浏览器使用 GPU 加速。但即使应用了这些“技巧”,我的明星背景也确实非常需要资源。一旦你打开我的网站,CPU 和 GPU 的使用率就会急剧上升并保持在相当高的水平。

我想知道是否有更好的方法来执行我想要的动画而不浪费这么多 CPU 或 GPU 功率。

我想在我的网站上添加移动星星的背景。我对此的解决方案是为每个星星创建一个 div,给它一个大小、背景颜色和带有关键帧的 CSS 动画。不透明度、x 和 y 位置以及动画的速度是随机的。

关键帧如下:

@keyframes linear-translate 
  0% 
    left: -10%;
    transform: rotateZ(360deg); /* rotateZ tricks the browser to use GPU acceleration for better performance  */
  
  100% 
    left: 110%;
  


@keyframes linear-translate-initial 
  0% 
    transform: translateX(0) rotateZ(360deg);
  
  100% 
    left: 110%;
  

以下是其中一个 div 元素的示例(带有尾风 CSS 类):

<div class="absolute block bg-gray-200 rounded-full" 
     style="left: 1%; top: 8%; width: 3px; height: 3px; opacity: 0.381289; 
     animation: 90.0069s linear 0s 1 normal none running linear-translate-initial, 
     110.007s linear 90.0069s infinite normal none running linear-translate;"></div>

链接到带有工作示例的代码框: https://codesandbox.io/s/starbackgroundreacttailwindcss-wzers?file=/src/Starfield.tsx

对于为什么这些动画消耗如此多的能量以及如何提高它们的效率有什么想法吗?毕竟只是横向翻译...

更新:

我尝试按照 Marco 的建议将星星分层到不同速度的 div 元素中。 我的结果可以在这里找到:

https://codesandbox.io/s/layeredstarbackgroundreacttailwindcss-wj71q?file=/src/App.tsx:392-445

不幸的是,“改进”并不是那么好。 CPU 使用率有所下降,但 GPU 使用率急剧上升。

【问题讨论】:

你可能想看看Particles.js。因为使用canvas 是处理大量对象的最佳方法。 【参考方案1】:

我已经在您的沙盒上玩了一会儿,是的,解决方案就是这么简单 - 只有很多/不同的动画/项目要为 CPU 处理,您可以在打开任务管理器并检查 CPU 时轻松看到沙盒在您的页面空闲时使用。在我的“小型”机器上,Firefox 使用高达 53% 的 CPU。当我减少脚本中的星星数量(减少到 10 颗)时,它会减少到 18% 左右。

我在从左到右移动时遇到了类似的问题,即“移动 div”背景带有阴影/渐变颜色和旋转...

到目前为止有趣的项目。 一个想法可能是在有限数量的层中固定多颗星,然后移动整个层(即使有 10 层,也只有 10 个对象在移动)...

是的,你不会有像单独计算/移动每颗星星那样的强烈效果,但有 10 层作为背景(我认为它是背景,对吧?)它不应该对观众产生任何明显的影响......

【讨论】:

我也想到了多层的这个想法。我只是还没有时间弄清楚细节,因为我想要一个连续的动画(它不应该在每次重复动画时都跳转)。最重要的是,网站的高度可能会发生变化(例如可扩展的 div 元素)。大小的变化也不应该导致恒星的那些“跳跃”。但是有可能实现你的建议。更少的动画对象 = 更少的 CPU / GPU 使用率 我尝试了你的分层星星的建议,只为包含星星的 div 设置动画。我的结果可以在这里找到:codesandbox.io/s/… 不幸的是,“改进”并不是那么好。 CPU 使用率有所下降,但 GPU 使用率急剧增加。

以上是关于为啥我的 CSS 动画会消耗这么多资源?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这段代码会消耗这么多堆?

为啥Java的socket.connect()会消耗100%的cpu资源?

虚拟滚动技术 --- 解决加载大量列表DOM导致页面卡顿

为啥我的 UIImage 占用这么多内存?

为啥TDengine比TimescaleDB消耗这么多存储空间?

为啥 Kernel#require 占用了我的应用程序资源的这么大块?