setTimeout 的最小毫秒值是多少?

IT技术 javascript timer cross-browser settimeout
2021-01-29 16:18:14

我想放

var minValue = 0;
if ( typeof callback == 'function' ) {
    setTimeout( callback, minValue );
}

当我用 JavaScript 实现回调函数时的这段代码。

但我发现现代浏览器和一些旧浏览器

有不同的最小超时值。

我知道零不能是最小值。

setTimeout 的最小值是多少

现代浏览器和一些旧浏览器的兼容性问题?

4个回答

我认为 10 将是所有浏览器中最可靠的最小值,因为我已经看到很多代码使用它。

但是,4ms 是 HTML5 的最小值

事实上,4ms 是由 HTML5 规范指定的,并且在 2010 年及以后发布的浏览器中是一致的。在 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) 之前,嵌套超时的最小超时值为 10 毫秒。

因此,如果嵌套级别小于 5,则 Chrome 中的最低值为“1 毫秒”。chrome.googlesource.com/ chromium/blink/+/master/Source/core/...
2021-03-14 16:18:14
对不起,这不是(不再?)真的。我只是在标准中找不到关于 4ms 延迟的声明,除了一条注释:“注意:定时器可以嵌套;但是,在五个这样的嵌套定时器之后,间隔被强制为至少四毫秒。” 进一步的好奇心让我在谷歌小组上发表这篇关于他们如何在 Chrome 中做到这一点的精彩帖子
2021-03-23 16:18:14
@TobbeBrolin 但是,我没有看到 WHATWG 的规范中反映了这种语言。看起来 W3C 和 WHATWG 不同意这一点。
2021-03-29 16:18:14
@TobbeBrolin 无论在实现中是否属实,它仍然在规范中:“如果当前运行的任务是由 setTimeout() 方法创建的任务,并且超时小于 4,则将超时增加到 4。”
2021-03-31 16:18:14

现代浏览器中的最小值为 4 毫秒(从 HTML5 开始),在此之前为 10 毫秒。请注意,这些时间从来都不是 100% 准确的。

@MaximPro 不确定理解您的评论。我的观点是,与这个答案所说的相反,对于不至少在第 5 嵌套级别的超时没有最小超时限制。onclick=e=>setTimeout(fn,0)如果没有其他东西阻止浏览器,那么将在不到 4 毫秒内执行 fn。(Chrome 中至少有 1 毫秒,但他们将其删除)
2021-03-12 16:18:14
@Kaiido 我只是强调嵌套计时器(将嵌套 5 次或更多次)之间的超时大约为 5 毫秒,仅此而已。
2021-03-18 16:18:14
@Kaiido 但实践表明,你永远不会得到等于 4 毫秒的超时,大约是 5 毫秒
2021-03-31 16:18:14
4ms 延迟仅适用于从 5 个嵌套级别进行调用时。
2021-04-05 16:18:14

setTimeout最有可能调用sleepSleep系统调用

实际机制,包括最小毫秒数,setTimeout是专有的和/或系统相关的,因为它们不在官方 ECMA 规范中。这取决于您的 Javascript 运行时,以及您运行它的系统。鉴于您的 Javascript 运行时不会增加大量开销,最小毫秒数取决于您的操作系统和硬件的时间片分辨率。最小的“可休眠”时间通常是系统调度算法为进程分配另一个时间片所需时间

例如,在 Windows(XP 后)上,sleep 系统调用的文档显示:

零值会导致线程将其时间片的剩余部分放弃给准备运行的任何其他线程。如果没有其他线程准备运行,则函数立即返回,线程继续执行。

这意味着,在极少数情况下,当前没有其他进程正在等待您的 Javascript 运行时进程正在运行硬件线程,它可能会在调用者完成执行后立即继续,具体取决于您的 Javascript 运行时被执行。不过,您可能不会经常观察到这种情况:)

我必须承认这个答案并不能说服我,因为它与我认为我对 javascirpt(主要是)单线程基于事件的执行的了解不符。你能指出任何参考文献说任何 js 实现调用sleep吗?
2021-03-20 16:18:14
我非常怀疑。特别sleep| Sleep与此相关的系统调用。我想 javascript 有它自己的调度机制,粒度最终将取决于该语言的特定浏览器实现。但是 javascript 是基于事件的,我认为它会在循环中检查事件,如果有任何计划的和“过期的”执行它们。这就是为什么它不准确(在这种情况下毫秒很大,因此应该期望准确度)以及为什么应该限制setTimeout()的时间参数。
2021-04-02 16:18:14
“它可能会立即继续,具体取决于您的 Javascript 运行时是如何实现的” -如果运行时正确实施,则在当前代码完成执行之前不会运行超时-即使您指定时间为 0,它仍将排队.
2021-04-05 16:18:14

本文测试 Firefox、Safari 和 Opera 并绘制性能图:

http://ejohn.org/blog/analyzing-timer-performance/

Firefox 2、Opera 和 Safari 都有 10 毫秒的底部窗口延迟

对于较旧的浏览器,您可以进行类似于该文章中的测试。我刚刚setInterval在 IE6使用了 10 毫秒的时间间隔进行了一次测试,结果平均为55毫秒setTimeout似乎在35ms 时更低

我在 Chromium 中运行了测试,并在10 毫秒的超时时间内获得了大约 11毫秒的平均值。我以 4 毫秒和 1 毫秒的间隔进行了尝试,两者都得到了大约 4.5毫秒另外,请记住,这些数字可能因操作系统而异。

如果你有兴趣,这里是测试代码:

<script>
// number of times to call setTimeout before calculating average
var ITERATIONS = 200;

window.onload = function()
{
    testTimeout(10, +new Date, 0, 0);
}

// calls setTimeout repeatedly at a specified interval, tracking the amount
// of time that passes between successive calls
function testTimeout(interval, last, sum, ii)
{
    var time = +new Date;
    var difference = time - last;
    sum += difference;
    if (ii % ITERATIONS == 1)
    {
        document.body.innerHTML = sum / ITERATIONS;
        sum = 0;
    }
    window.setTimeout(
        function() {
            testTimeout(interval, time, sum, ii + 1)
        }, interval);
}
</script>