SetInterval发生得比预期的快

SetInterval happening faster than desired

本文关键字:SetInterval      更新时间:2023-09-26

我一直在使用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 fps。

我读过一篇很有启发性的关于Mozilla setTimeout的文章,其中提到了"夹紧",我想这可能是一个原因。然而,对于60fps,超时将是16.6ms,比使用的任何夹子都要高。

我也认为这可能是一个计时器错误,给我一个或两个帧,但测试与20000ms返回相同的平均fps,所以它不是计时器。

你知道我做错了什么吗?这是一种非常奇怪的行为。

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

这些都符合你观察到的行为

最重要的是,你有setTimeout和setInterval的变化无常,而不是在所要求的延迟下运行,所以如果系统突然变得繁忙(比如响应网络请求,滚动动作等),帧速率将变慢或变得不稳定,试图赶上。

不幸的是,这个方法不能产生一致的结果。您必须考虑所讨论的脚本的实际执行时间,尽管它可能很短。

我听说requestAnimationFrame更适合这个用途。

来自Mozilla Developer Network的一个关于它的片段。

一篇关于它的好文章