SetInterval的发生速度比预期的要快

时间:2013-03-05 05:15:21

标签: javascript html5 setinterval

我一直在玩HTML5和Canvas,所以我很欣赏能为我正在做的事情提供恒定的帧率。为此,我试图使用javascript的setInterval,但似乎setInterval循环比期望的更快。

出于测试目的,我编写了一个小测试脚本,如下所示:

var start = new Date();
var frames = 0;

setInterval(function() { 
    frames++;
    var d = new Date();
    if (d.getTime() - start.getTime() > 1000) {
        console.log(frames);
        frames = 0;
        start = d;
    }
}, 1000/60);

这个脚本据说打印了一秒钟内计算了多少“帧”。如果setInterval工作正常,它将在控制台上不断打印“60”。但是,Chrome和Firefox每秒给我63帧,而Internet Explorer 9给我每秒66到67帧(总是最差的罪犯)。

将1000毫秒提升到20000平均为Chrome提供了62.5 fps,Firefox上为62.4 fps,Internet Explorer为66.0。

我已经阅读了关于setTimeout的very enlightening article on Mozilla,他们提到了“夹紧”,我认为这可能是一个可能的原因。但是,对于60fps,超时时间为16.6ms,高于任何使用的钳位。

我还以为它可能是一个定时器错误,让我关闭了一两帧,但20000ms的测试返回了相同的平均fps,所以它也不是定时器。

关于我做错什么的任何想法?这是一种非常奇怪的行为。任何反馈都将不胜感激。

2 个答案:

答案 0 :(得分:1)

setTimeout的延迟是一个整数(毫秒)。 1000/6016.67,会被截断为161000/1662.5。 IE的时钟以15ms的增量运行,因此它可能以15ms的间隔运行该函数,因此66.7 fps。

所有这些都符合您观察到的行为。

最重要的是,你有变量setTimeout和setInterval没有完全按照请求的延迟运行,所以如果系统突然变忙(比如响应网络请求,滚动动作等),帧速率会变慢或者变得生涩起来试图赶上来。

答案 1 :(得分:0)

不幸的是,这种方法不会产生一致的结果。您必须考虑相关脚本的实际执行时间,尽可能短。

我听说requestAnimationFrame可以更好地用于此用途。

A snippet from the Mozilla Developer Network about it.

A nice article about it