加快setInterval

时间:2011-03-14 13:11:16

标签: javascript

我知道javascript中的setInterval方法至少有1毫秒。我可以加快速度吗?喜欢使用微秒?

我需要这个:

我制作了一个画布css / js动画。它是一条简单的线条,可以治愈并恢复生产线。我有一个滑块来调整这个动画的速度。所以最低的滑块值会非常快,最高的滑块真的很慢。这是可以理解的吗?谢谢!

6 个答案:

答案 0 :(得分:23)

更新

请注意,写这个答案时,问题是:

  

我知道setInterval方法中至少有1毫秒   JavaScript的。我可以加快速度吗?喜欢使用微秒?

后来它被编辑为包含有关画布动画的信息,并且使用window.requestAnimationFrame方法时,正确答案将使用该新信息:

function step(timestamp) {
  // do something for every frame
  window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);

step回调每次调用时都会获得一个DOMHighResTimeStamp时间戳,精度为1微秒作为参数,每次刷新屏幕时都会返回一次(不需要再绘制任何内容)经常因为无论如何都不会显示。)

最初的问题是关于加快setInterval方法的问题,而我最初的答案是关于做一般事情的频率高于the minimum delay setInterval允许(根据the WHATWG specification8.4 Timers部分的嵌套级别大于5的4ms,或根据this post by James Robinson的4或更高级别的嵌套级别为4ms ,历史上it used to work differently)。

原始答案:

我真的不知道你想做什么,所以我只能根据人们通常想做的事情来说话。

如果你想使用微秒调用setInterval,那么你想要运行的代码必须花费少于一毫秒,否则在单线程事件循环中没有意义。

你不必担心阻塞浏览器几毫秒,所以我建议使用这样的东西 - 而不是:

setInterval(function () {
    // YOUR CODE
}, 1/100);

尝试做:

setInterval(function () {
    for (var i = 0; i < 1000; i++) {
        // YOUR CODE
    }
}, 10);

通过避免回调调用开销实际上可以提高代码效率,并且更长的间隔将使代码运行更加可预测。

也没有人会注意到你的代码每1/100秒突发运行1000次,因为由于操作系统级的进程调度,浏览器本身已经在这样的突发中运行,并且无论如何,屏幕都不会更快刷新。

实验

好的,现在进行一些实验。尝试使用此代码查看浏览器实际上最短的间隔时间:

var start = new Date();
var i = 0, interval = setInterval(function(){
    if (++i >= 1000) {
        var end = new Date();
        alert("The average interval was "
              + ((end-start)/1000)) + " milliseconds";
        clearInterval(interval);
    }
}, 0);

请注意,它在同一浏览器上甚至不一致。例如,这取决于您的系统负载。

测试您的浏览器

如果您愿意,请尝试THIS FIDDLE测试您的浏览器并将结果发布到评论中。我想知道会有什么记录。

答案 1 :(得分:5)

最短时间因浏览器而异。这里有一个很好的解释:http://www.adequatelygood.com/2010/2/Minimum-Timer-Intervals-in-JavaScript

答案 2 :(得分:4)

请注意,某些浏览器不会接受小于50毫秒的间隔。如果您传递较小的间隔,他们将使用他们能够使用的最小间隔。

答案 3 :(得分:2)

仅供参考,在每个间隔之间执行它会少于几毫秒是没用的,因为画布操作需要几毫秒来完成他们自己的事情,同时阻止你的主循环(单线程)。执行1/100毫秒实际上在经典浏览器中向上舍入为16,在chrome中为5毫秒。

如果你想在javascript中将动画计时到微秒,那你就错了,因为那是徒劳的目标。垃圾收集,繁忙的循环时间差异会伤害你,更不用说如果画得太快你可能会被撕裂。

解决方案:使用requestAnimationFrame从浏览器中获取最大FPS,并且不要忘记提供setInterval(...,16)的回退。

https://developer.mozilla.org/en/DOM/window.mozRequestAnimationFrame http://dev.chromium.org/developers/design-documents/requestanimationframe-implementation

答案 4 :(得分:0)

我知道这是一个老问题,但仍然没有接受答案。

您不需要更短的间隔来增加线条弯曲的速度。您保持间隔相同,这是您的帧率,您只需更改行的状态之间的步进。如果框架快速弯曲,它会在框架之间弯曲更多。

这是我一直在玩的东西的例子。

var radius = 0;
var hor = 0;
var frameTime = 1000/60;
var step = 1;

setInterval(function () {
    var draw = document.getElementById('draw');
    var context = draw.getContext('2d');

    draw.width = draw.width;

    context.fillStyle = '#ffffff';
    context.beginPath();
    context.arc(draw.width/2,draw.height/2,radius,0,Math.PI*2,true);
    context.closePath();
    context.stroke();
    context.fill();

    radius = (radius+(step*frameTime))%(draw.height/2);
}, frameTime);

这是一个非常简单的动画,只是一个增长到画布大小的圆圈,然后从零开始。这里,变量“step”控制动画的速率。 'frameTime'是帧之间的时间。

我希望我已经正确理解了问题所在。我知道很久以前你可能已经克服了它,但我认为最好在这里为任何有类似问题的人提供答案。

答案 5 :(得分:-2)

我不确定它是否可行,但尝试潜水一毫秒以进一步分解。 e.g。

setTimeout(“moretext()”,1/100);