安排更新“线程”在 JS/WebGL 中
目前,我正在使用 requestAnimationFrame
渲染 WebGL 内容,该内容的运行速度(理想情况下)为 60 FPS。我还同时安排了一个“更新”进程,该进程使用 setTimeout
处理 AI、物理等。我使用后者是因为我实际上只需要每秒更新对象大约 30 次,而且它并不是绘制序列的一部分;为实际渲染过程节省剩余的 CPU 似乎是个好主意,因为我的大多数动画都是相当硬件密集型的。
我的问题是最佳实践之一。 setTimeout
和 setInterval
对电池寿命和 CPU 消耗并不是特别友好,尤其是当浏览器未处于焦点时。另一方面,使用 requestAnimationFrame(或将更新直接绑定到现有渲染阶段)可能会每秒强制执行比严格必要的更新更多的更新,并且当浏览器不在时可能会完全停止更新焦点或在浏览器认为不需要“动画”的其他时间。
更新内容但不渲染内容的最佳做法是什么?
Currently, I am rendering WebGL content using requestAnimationFrame
which runs at (ideally) 60 FPS. I'm also concurrently scheduling an "update" process, which handles AI, physics, and so on using setTimeout
. I use the latter because I only really need to update objects roughly 30 times per second, and it's not really part of the draw sequence; it seemed like a good idea to save the remaining CPU for actual render passes, since most of my animations are fairly hardware intensive.
My question is one of best practices. setTimeout
and setInterval
are not particularly kind to battery life and CPU consumption, especially when the browser is not in focus. On the other hand, using requestAnimationFrame
(or tying the updates directly into the existing render phase) will potentially enforce far more updates every second than are strictly necessary, and may stop updating altogether when the browser is not in focus or at other times the browser deems unnecessary for "animation".
What is the best course of action for updating, but not rendering content?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
。说实话:
requestAnimationFrame
也不是。不同之处在于,当您离开选项卡时,RAF 会自动关闭。如果您使用 Page Visibility API,因此实际上,如果使用得当的话,两者之间的功耗问题大致相同。除此之外,
setTimeout\Interval
非常适合您的情况。您可能需要注意的唯一一件事是您将很难使其与渲染循环完美同步。在某些情况下,您可能会在动画更新命中之前绘制过多次,这可能会导致轻微的卡顿。如果您以 60hz 渲染并以 30hz 更新,这应该不是一个大问题,但您需要注意这一点。如果与渲染循环保持完美同步对您来说很重要,您可以简单地使用 if(framecount % 2) { updateLogic(); } 在 RAF 回调的顶部,这有效地将您的更新限制为 30hz(每隔一帧),并且它始终与绘图同步。
Let's be honest: Neither is
requestAnimationFrame
. The difference is that RAF automatically turns off when you leave the tab. That behavior can be emulated withsetTimeout
if you use the Page Visibility API, though, so in reality the power consumption problems between the two are about on par if used intelligently.Beyond that, though,
setTimeout\Interval
is perfectly appropriate for use in your case. The only thing that you may want to be aware of is that you'll be hard pressed to get it perfectly in sync with the render loop. You'll have cases where you may draw one too many times before your animation update hits, which can lead to minor stuttering. If you're rendering at 60hz and updating at 30hz it shouldn't be a big issue, but you'll want to be aware of it.If staying perfectly in sync with the render loop is important to you, you could simply have a
if(framecount % 2) { updateLogic(); }
at the top of your RAF callback, which effectively limits your updates to 30hz (every other frame) and it's always in sync with the draw.