【问题标题】:Scheduling update "threads" in JS / WebGL在 JS / WebGL 中安排更新“线程”
【发布时间】:2012-01-09 02:20:10
【问题描述】:

目前,我正在使用requestAnimationFrame 渲染 WebGL 内容,它以(理想情况下)60 FPS 运行。我还在同时安排一个“更新”进程,该进程使用setTimeout 处理 AI、物理等。我使用后者是因为我只需要每秒更新大约 30 次对象,而且它并不是绘制序列的一部分;为实际渲染通道节省剩余的 CPU 似乎是个好主意,因为我的大多数动画都相当消耗硬件。

我的问题是最佳实践之一。 setTimeoutsetInterval 对电池寿命和 CPU 消耗不是特别友好,尤其是当浏览器不在焦点上时。另一方面,使用requestAnimationFrame(或将更新直接绑定到现有渲染阶段)可能会每秒强制执行比严格必要的更新多得多,并且可能在浏览器不在焦点时或在其他时间完全停止更新浏览器认为“动画”是不必要的。

更新而不是渲染内容的最佳行动方案是什么?

【问题讨论】:

    标签: javascript settimeout webgl updates requestanimationframe


    【解决方案1】:

    setTimeout 和 setInterval 对电池寿命和 CPU 消耗并不是特别友好

    说实话:requestAnimationFrame 也不是。不同之处在于,当您离开选项卡时,RAF 会自动关闭。但是,如果您使用 Page Visibility API,则可以使用 setTimeout 模拟该行为,因此实际上,如果智能使用,两者之间的功耗问题大致相同。

    不过,除此之外,setTimeout\Interval 非常适合在您的情况下使用。您可能需要注意的唯一一件事是,您将很难让它与渲染循环完美同步。在某些情况下,您可能会在动画更新命中之前绘制太多次,这可能会导致轻微的卡顿。如果您以 60hz 进行渲染并以 30hz 进行更新,这应该不是什么大问题,但您需要注意这一点。

    如果与渲染循环保持完美同步对您很重要,您可以简单地在 RAF 回调的顶部添加一个 if(framecount % 2) { updateLogic(); },这有效地将您的更新限制为 30hz(每隔一帧)并且它始终保持同步与平局。

    【讨论】:

    • 谢谢!我能想到直接附加到渲染循环的唯一缺点是当用户切换选项卡时更新可能会暂停,但现在我正在考虑它,这可能是更可取的结果(因为如果他们切换了选项卡作为用户,他们显然无法从更新中受益)。任何迫切需要在后台更新的内容都可以进入自己的时间间隔。
    猜你喜欢
    • 2020-04-27
    • 2016-07-16
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 2013-11-28
    • 1970-01-01
    相关资源
    最近更新 更多