受GPU限制的动画是否仍受CPU负载影响? [英] Are GPU-bound animations still affected by CPU load?

查看:85
本文介绍了受GPU限制的动画是否仍受CPU负载影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用以下样式为div创建了一个合成层:

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

然后我使用Web动画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可以独立地对其进行操作,而不必担心计算页面其他部分的几何形状./p>

我不理解的是,如果我调用一个占用大量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/

解决方案

是的,它们仍然可能会受到CPU负载的影响.
更新渲染 算法是事件循环的一部分,因此,如果您以某种方式阻止事件循环,那么也会阻止渲染.

现在,鼓励实施者事件循环" ,因为它们遇到了运行时间长的代码,因此UI仍然可以是响应式的(并且非js驱动的动画可以继续运行),但这只是鼓励,并且所有实现方式都不一样道路.

例如,在我的Firefox上,我看不到您的脚本的任何速度降低,甚至也看不到下面更具攻击性的速度,而在Chrome上,我可以清楚地看到渲染被阻止.

现在要避免这种情况,正如评论中所说,真正的防弹解决方案是在第二个线程中运行阻止脚本

I have created a compositing layer for a div with the following styles:

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

I then apply an animation to it using the 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
  }
);

From my understanding, this animation is now being handled by the GPU and this layer is independent from other layers so the GPU can act upon on it in isolation without having to worry about calculating the geometry of other parts of the page.

What I don't understand is if I invoke a CPU intensive function, that animation will halt entirely while the function is running, and will pick up again when the function exits:

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);

Is there any way to prevent this?

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

解决方案

Yes they may still get affected by CPU load.
The update the rendering algorithm is part of the Event Loop, so if somehow you do block the event loop, you also do block the rendering.

Now, implementors are encouraged to "spin the event loop" when they meet a long running code, so that UI can still be reactive (and non-js powered animations can keep running), but this is just an encouragement and all implementations don't do it the same way.

For instance, on my Firefox, I don't see any slowdown from your script, nor even from the more aggressive one below, while on my Chrome I can clearly see the rendering being blocked.

Now to avoid this, as has been said in comment, the real bullet proof solution would be to run your blocking script in a second thread 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);
}

<div id="box"></div>

这篇关于受GPU限制的动画是否仍受CPU负载影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆