Chrome: tempos limite / intervalo suspensos em guias de plano de fundo?

Eu estava testando a precisão do setTimeout usando este teste . Agora notei que (como esperado) setTimeout não é muito preciso, mas a maioria dos aparelhos não é muito imprecisa. Agora, se eu executar o teste no Chrome e deixá-lo executar em uma guia de fundo (assim, alternando para outra guia e navegar lá), retornando para o teste e inspecionando os resultados (se o teste terminar) eles são drasticamente alterados. Parece que os tempos limite foram muito mais lentos. Testado em FF4 ou IE9 isso não ocorreu.

Parece que o Chrome suspende ou, pelo menos, desacelera a execução do javascript em uma guia sem foco. Não foi possível encontrar muito na net sobre o assunto. Isso significaria que não podemos executar tarefas em segundo plano, como por exemplo, verificando periodicamente em um servidor usando chamadas XHR e setInterval (eu suspeito de ver o mesmo comportamento para setInterval , vai escrever um teste se o tempo estiver comigo).

Alguém já encontrou isso? Haveria uma solução alternativa para essa suspensão / desaceleração? Você chamaria de um bug e eu deveria arquivar como tal?

Eu perguntei recentemente sobre isso e é comportamento por design. Quando uma guia está inativa, somente no máximo uma vez por segundo a function é chamada. Aqui está a alteração do código .

Talvez isso ajude: Como posso fazer o setInterval funcionar quando uma guia está inativa no Chrome?

TL; DR: use Web Workers .

Existe uma solução para usar os Web Workers, porque eles são executados em processos separados e não são retardados

Eu escrevi um pequeno script que pode ser usado sem alterações no seu código – ele simplesmente sobrescreve as funções setTimeout, clearTimeout, setInterval, clearInterval

Basta incluí-lo antes de todo o seu código

http://github.com/turuslan/HackTimer

Atualizei meu núcleo do jQuery para o 1.9.1 e resolvi a discrepância de Interval em abas inativas. Eu tentaria isso primeiro, depois olhe para outras opções de substituição de código.

Eu liberei o pacote npm de intervalo de trabalho que a implementação de setInterval e clearInterval com o uso de Web-Workers para manter em funcionamento em abas inativas para o Chrome, Firefox e IE.

A maioria dos navegadores modernos (Chrome, Firefox e IE), os intervalos (timeres de janela) são impedidos de triggersr com uma frequência maior do que uma vez por segundo nas guias inativas.

Você pode encontrar mais informações sobre

https://developer.mozilla.org/pt-BR/docs/Web/API/WindowOrWorkerGlobalScope/setInterval

https://developer.mozilla.org/pt-BR/docs/Web/API/Web_Workers_API/Using_web_workers#Timeouts_and_intervals

A reprodução de um som ~ vazio força o navegador a manter o desempenho – descobri-o depois de ler este comentário: Como fazer com que o JavaScript seja executado na velocidade normal no Chrome mesmo quando a guia não está ativa?

Eu preciso de um desempenho ilimitado sob demanda para um jogo de navegador que usa WebSockets, então sei por experiência que usar WebSockets não garante desempenho ilimitado, mas a partir de testes, reproduzir um arquivo de áudio parece garantir isso

Aqui estão dois loops de áudio vazios que eu criei para essa finalidade, você pode usá-los livremente, comercialmente: http://adventure.land/sounds/loops/empty_loop_for_js_performance.ogg http://adventure.land/sounds/loops/empty_loop_for_js_performance.wav

(Eles incluem ruído de -58db, -60db não funciona)

Eu os executo, sob demanda do usuário, com o 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, }); } 

É triste que não haja nenhum método interno para ativar / desativar o desempenho completo do JavaScript, mas, mesmo assim, os mineiros de criptografia podem seqüestrar todos os seus threads de computação usando Web Workers sem nenhum prompt: |