【问题标题】:Are GPU-bound animations still affected by CPU load?GPU 绑定的动画是否仍受 CPU 负载的影响?
【发布时间】:2019-06-03 06:09:00
【问题描述】:

我为具有以下样式的 div 创建了一个合成层:

div {
  position: absolute;
  height: 50px;
  width: 50px;
  background: #900;
  top: 100px;
  left: 200px;
  will-change: transform;
  transform: translateZ(0);
}

然后我使用 Web Animation API 对其应用动画:

document.getElementById("box").animate(
  [
    { transform: 'rotate(0) translate3D(-50%, -50%, 0)' },
    { transform: 'rotate(360deg) translate3D(-50%, -50%, 0)' }
  ], {
    duration: 500,
    iterations: Infinity
  }
);

据我了解,此动画现在由 GPU 处理,并且该层独立于其他层,因此 GPU 可以单独对其进行操作,而不必担心计算页面其他部分的几何形状。

我不明白的是,如果我调用一个 CPU 密集型函数,该动画将在函数运行时完全停止,并在函数退出时再次启动:

function mySlowFunction(baseNumber) {
    console.time('mySlowFunction');
    var result = 0; 
    for (var i = Math.pow(baseNumber, 10); i >= 0; i--) {       
        result += Math.atan(i) * Math.tan(i);
    };
    console.timeEnd('mySlowFunction');
    return result;
}

setTimeout(() => mySlowFunction(5), 3000);

有什么办法可以防止这种情况发生吗?

https://jsfiddle.net/Lsmw85rv/4/

【问题讨论】:

    标签: javascript css css-animations


    【解决方案1】:

    是的,它们可能仍会受到 CPU 负载的影响。
    update the rendering 算法是事件循环的一部分,所以如果你确实阻塞了事件循环,你也会阻塞渲染。

    现在,鼓励实现者在遇到长时间运行的代码时"spin the event loop",这样 UI 仍然可以是响应式的(并且非 js 驱动的动画可以继续运行),但这只是一种鼓励,所有实现都不会'不要这样做。

    例如,在我的 Firefox 上,我看不到您的脚本有任何减速,甚至从下面更激进的脚本中也看不到,而在我的 Chrome 上,我可以清楚地看到渲染被阻止。

    现在为了避免这种情况,正如评论中所说,真正的防弹解决方案是在第二个线程 using a Web Worker 中运行您的阻塞脚本。

    document.getElementById("box").animate(
      [{
          transform: 'rotate(0) translate3D(-50%, -50%, 0)'
        },
        {
          transform: 'rotate(360deg) translate3D(-50%, -50%, 0)'
        }
      ], {
        duration: 500,
        iterations: Infinity
      }
    );
    
    function mySlowFunction(baseNumber) {
      console.time('mySlowFunction');
      const now = performance.now();
      while (performance.now() - now < baseNumber * 1000);
      console.timeEnd('mySlowFunction');
    }
    
    setTimeout(() => mySlowFunction(3), 3000);
    #box {
      position: absolute;
      height: 50px;
      width: 50px;
      background: #900;
      top: 100px;
      left: 200px;
      will-change: transform;
      transform: translateZ(0);
    }
    &lt;div id="box"&gt;&lt;/div&gt;

    【讨论】:

    • 我在研究中没有遇到过这个问题,我读过的大部分内容都是这样的:The animation is no longer bound to the CPU. Even if you run a very intensive JavaScript task, the animation will still run quickly.。我假设 GPU 负责渲染动画,独立于事件循环,因为它的层与页面的其他元素隔离。我现在正试图了解 GPU 提供的价值,因为到目前为止我一直认为渲染独立性是它的主要优势。
    • 首先,不确定这是否会受益于硬件加速,这实际上取决于最终用户的设备。现在在 GPU 上做的是合成,所以即使你的所有动画层都在 GPU 上处理过,GPU 仍然需要最后一次页面更新,以便它可以将所有层“合成”在一起。最后一次更新是由 CPU 在事件循环的“更新渲染”步骤中发送的。
    猜你喜欢
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2011-12-06
    • 2017-08-17
    相关资源
    最近更新 更多