Chrome:超时/间隔在后台标签中暂停?

qf9go6mv  于 2022-12-06  发布在  Go
关注(0)|答案(7)|浏览(309)

我使用this test测试setTimeout的准确性。(如预期的那样)setTimeout不是很准确,但对于大多数设备来说并不是非常不准确。现在如果我在Chrome中运行测试,让它在后台选项卡中运行(因此,切换到另一个选项卡并在那里浏览),返回测试并检查结果(如果测试已完成),结果发生了显著变化。看起来超时的运行速度慢了很多。在FF 4或IE9中进行了测试,但没有发生这种情况。
所以看起来Chrome在一个没有焦点的标签页中挂起或者至少减慢了javascript的执行速度。在互联网上找不到关于这个主题的信息。这意味着我们不能运行后台任务,比如使用XHR调用和setInterval在服务器上定期检查(我怀疑setInterval也会出现同样的行为,如果时间允许我会写一个测试)。
有人遇到过这种情况吗?对于这种暂停/减速有什么解决办法吗?你会称之为bug吗?我应该这样归档吗?

vhmi4jdf

vhmi4jdf1#

我最近问过这个问题,这是设计的行为。当一个标签不活动时,最多每秒只调用一次函数。这里是code change
也许这会有所帮助:How can I make setInterval also work when a tab is inactive in Chrome?

    • TL; DR:使用Web工作进程**。
djmepvbi

djmepvbi2#

有一个使用Web Workers的解决方案,因为它们在单独的进程中运行,不会减慢速度
我编写了一个小脚本,可以在不更改代码的情况下使用-它只覆盖函数setTimeout、clearTimeout、setInterval、clearInterval
只需将其包含在所有代码之前
http://github.com/turuslan/HackTimer

mzmfm0qo

mzmfm0qo3#

播放空的声音会迫使浏览器保留性能,我是在阅读了这篇评论后发现的:如何使JavaScript在Chrome中以正常速度运行,即使标签页不活动?
使用source of that comment found here
Chromium内部人士还澄清说,对于所有“播放音频”的背景选项卡以及任何“存在活动WebSocket连接”的页面,积极的节流将被自动禁用。
对于使用WebSockets的浏览器游戏,我需要无限的按需性能,因此根据经验,我知道使用WebSockets并不能确保无限的性能,但从测试来看,播放音频文件似乎可以确保这一点
这里有两个空的音频循环,我创建了这个目的,你可以自由地使用它们,商业:http://adventure.land/sounds/loops/empty_loop_for_js_performance.ogghttp://adventure.land/sounds/loops/empty_loop_for_js_performance.wav
(They包括-58db噪音,-60db不起作用)
我根据用户需求使用Howler.js播放它们:https://github.com/goldfire/howler.js

function performance_trick()
{
    if(sounds.empty) return sounds.empty.play();
    sounds.empty = new Howl({
        src: ['/sounds/loops/empty_loop_for_js_performance.ogg','/sounds/loops/empty_loop_for_js_performance.wav'],
        volume:0.5,
        autoplay: true, loop: true,
    });
}

遗憾的是,没有内置的方法来默认打开/关闭JavaScript的全部性能,然而,加密矿工可以在没有任何提示的情况下使用Web Workers劫持所有的计算线程。

nhn9ugyo

nhn9ugyo4#

我已经发布了worker-interval npm包,其中setInterval和clearInterval实现使用Web工作者来保持和运行Chrome、Firefox和IE的非活动选项卡。
大多数现代浏览器(Chrome、Firefox和IE),间隔(窗口计时器)被钳制为在不活动的选项卡中每秒触发不超过一次。
有关详细信息,请访问
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Timeouts_and_intervals

hvvq6cgz

hvvq6cgz5#

我将jQuery核心更新到了1.9.1,它解决了非活动标签中的间隔差异。

eivnm1vs

eivnm1vs6#

下面是我的解决方案,它获取当前的毫秒数,并将其与创建函数时的毫秒数进行比较。对于interval,它将在运行函数时更新毫秒数。您也可以通过id获取interval/timeout。

<script>

var nowMillisTimeout = [];
var timeout = [];
var nowMillisInterval = [];
var interval = [];

function getCurrentMillis(){
    var d = new Date();
    var now = d.getHours()+""+d.getMinutes()+""+d.getSeconds()+""+d.getMilliseconds();
    return now;
}

function setAccurateTimeout(callbackfunction, millis, id=0){
    nowMillisTimeout[id] = getCurrentMillis();
    timeout[id] = setInterval(function(){ var now = getCurrentMillis(); if(now >= (+nowMillisTimeout[id] + +millis)){callbackfunction.call(); clearInterval(timeout[id]);} }, 10);
}

function setAccurateInterval(callbackfunction, millis, id=0){
    nowMillisInterval[id] = getCurrentMillis();
    interval[id] = setInterval(function(){ var now = getCurrentMillis(); if(now >= (+nowMillisInterval[id] + +millis)){callbackfunction.call(); nowMillisInterval[id] = getCurrentMillis();} }, 10);
}

//usage
setAccurateTimeout(function(){ console.log('test timeout'); }, 1000, 1);

setAccurateInterval(function(){ console.log('test interval'); }, 1000, 1);

</script>
hgtggwj0

hgtggwj07#

对于单元测试,您可以使用以下参数运行chrome/chrome:--disable-background-timer-throttling

相关问题