setInterval是否会占用大量CPU资源?

85

我看到过一些文章说 setInterval 影响CPU性能。我写了一个使用 setInterval 的脚本并监控了CPU使用率,但是没有注意到变化。我想知道是否有什么我错过的东西。

这段代码每100毫秒检查URL中哈希(#后面的内容)是否更改,如果更改,则使用AJAX加载页面。如果没有更改,则不执行任何操作。这种方式是否会导致CPU问题。


3
取决于被调用的函数和你所指定的时间量。明显地,每100毫秒调用一个1000行代码的函数会占用大量CPU资源。 - Shaz
2
在Chrome浏览器中,如果标签页处于非活动状态,间隔函数每秒只会被调用一次。因此,如果您的网站/应用程序处于非活动状态,它肯定是CPU友好的。 - pimvdb
需要轮询更改吗?你不能为所有锚点添加点击处理程序吗? - davin
谢谢大家的回复,它们非常有帮助。 - Ryuku
@davin:是的,我这样做了,但问题是如果用户点击了返回按钮或手动更改了URL。 - Ryuku
显示剩余2条评论
6个回答

87

我认为setInterval不会自身引起严重的性能问题。我猜这个声誉可能来自一个更早的时代,当时CPU的功率较低。

然而,您可以通过以下方式提高性能,这也是明智的:

  1. 将一个函数传递给setInterval,而不是字符串。
  2. 尽可能少地设置间隔。
  3. 使间隔时间尽可能长。
  4. 每次运行的代码尽可能简短和简单。

不要过早优化 - 当没有问题时,不要让生活变得困难。

然而,在您的特定情况下,您可以在支持它的浏览器中使用onhashchange事件,而不是超时。


2
谢谢您的建议。这个帖子的所有回复都非常有帮助,我感谢大家。我选择了这个答案,因为onhashchange非常有用。 - Ryuku
1
哇,非常详尽而简洁的答案!谢谢你的建议! - Yes Barry
2
我会为“不要过早优化”单独点赞。非常简洁明了,非常有帮助。 - ghukill

19

我倒是更愿意说相反的情况。正确使用setTimeoutsetInterval,可以极大地减少浏览器的CPU使用率。例如,使用setTimeout而不是使用forwhile循环,不仅能减少CPU使用强度,还能保证浏览器有机会更频繁地更新UI队列,因此长时间运行的进程不会冻结和锁定用户体验。

但总的来说,如果在您的网站上同时运行了大量的setInterval,可能会使事情变慢。20个同时运行的间隔,无论是更多还是更少的工作,都会影响展示效果。当然,你也可能把其他部分搞砸,但这并不是setInterval的问题。

另外,顺便说一下,您不需要像那样检查哈希值。有事件可以做到这一点:

onhashchange

当哈希值发生变化时将会被触发。

window.addEventListener('hashchange', function(e) {
    console.log('hash changed, yay!');
}, false);

14

不,setInterval 本身并不会导致CPU过度使用。但是如果您有很多间隔时间很短的间隔运行(或者一个相对较长的间隔时间内运行的非常复杂的操作), 那么根据您的间隔时间做什么以及它们多频繁地执行,这可能很容易导致CPU过度使用。

我不认为每 100 毫秒检查一次URL会出现任何问题,尽管个人建议将间隔时间增加到250毫秒,因为我不认为两者之间的差异会被典型用户注意到,并且基本上我会尝试使用最长的超时间隔,特别是一些大部分时间都无需操作的事情。


4

这里有一些营销用语,使用了“CPU密集型”的术语。实际上的意思是“比某些替代方案更加CPU密集型”。它并不像“游戏或压缩算法那样使用大量的CPU功率”那样“CPU密集型”。

解释:

一旦浏览器放弃控制权,它就依赖于底层操作系统和硬件的中断来接收控制并发出JavaScript回调。这些中断之间的持续时间越长,硬件就可以进入低功耗状态,从而显著降低功耗。默认情况下,Microsoft Windows操作系统和基于Intel的处理器使用15.6毫秒分辨率进行这些中断(每秒64个中断)。这使得基于Intel的处理器可以进入最低电源状态。因此,Web开发人员在使用setTimeout(0)时,在HTML4浏览器(包括早期版本的Internet Explorer和Mozilla Firefox)中通常只能实现64个回调/秒。在过去的两年中,浏览器试图通过更改节能的Windows系统设置并防止硬件进入低功耗状态来增加setTimeout和setInterval API每秒可接收的回调次数。HTML5规范甚至建议每秒250个回调。这种高频率可能导致功耗增加40%,影响电池寿命、运营成本和环境。此外,这种方法并没有解决提高CPU效率和调度的核心性能问题。

来自http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html


4

在您的情况下,不会有任何问题。但如果您在canvas中进行大量动画或使用webgl,则会出现一些CPU问题,因此您可以使用requestAnimationFrame。

请参考此链接关于requestAnimationFrame


2

函数时间 > 间隔时间是不好的,您无法知道 CPU 何时会出现卡顿或变慢,并且它会堆叠在正在进行的函数之上,直到计算机冻结。使用 settimeout 或更好的 process.nextick,在 settimeout 中使用回调。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接