Eu estava testando a precisão do setTimeout
uso deste teste . Agora notei que (como esperado) setTimeout
não é muito preciso, mas para a maioria dos aparelhos não é dramaticamente impreciso. Agora, se eu executar o teste no Chrome e deixá-lo em uma guia em segundo plano (alternando para outra guia e navegando lá), retornando ao teste e inspecionando os resultados (se o teste terminar), eles serão alterados drasticamente. Parece que os tempos limite estiveram muito mais lentos. Testado em FF4 ou IE9, isso não ocorreu.
Parece que o Chrome suspende ou pelo menos diminui a execução do javascript em uma guia que não tem foco. Não foi possível encontrar muito na rede sobre o assunto. Isso significaria que não podemos executar tarefas em segundo plano, como, por exemplo, verificar periodicamente em um servidor usando chamadas XHR e setInterval
(eu suspeito de ver o mesmo comportamento setInterval
, escreveremos um teste se houver tempo comigo).
Alguém já encontrou isso? Haveria uma solução alternativa para essa suspensão / desaceleração? Você chamaria isso de bug e devo arquivá-lo como tal?
fonte
transition
, portanto nem todos os divs fazem a transição ao mesmo tempo, mas na verdade 15ms um após o outro, criando algum efeito contínuo. Quando vou para outra guia e volto depois de um tempo, todos os divs são transferidos ao mesmo tempo e osetTimeOut
é completamente ignorado. Não é um grande problema para o meu projeto, mas é uma adição estranha e indesejada.Respostas:
Recentemente, perguntei sobre isso e é comportamento por design. Quando uma guia está inativa, somente no máximo uma vez por segundo a função é chamada. Aqui está a alteração do código .
Talvez isso ajude: Como posso fazer o setInterval também funcionar quando uma guia está inativa no Chrome?
TL; DR: use Web Workers .
fonte
Existe uma solução para usar Web Workers, porque eles são executados em processo separado e não são mais lentos
Eu escrevi um pequeno script que pode ser usado sem alterações no seu código - ele simplesmente substitui as funções setTimeout, clearTimeout, setInterval, clearInterval
Basta incluí-lo antes de todo o seu código
http://github.com/turuslan/HackTimer
fonte
new Worker('data:text/javascript,(' + function myWorkerCode () { /*...*/ } + '()')
. Também é uma boa maneira de verificar se você possui suporte à expressão de importação:try { eval('import("data:text/javascript,void 0")') } catch (e) { /* no support! */ }
Tocar um som ~ vazio força o navegador a manter o desempenho - eu o descobri depois de ler este comentário: Como fazer o JavaScript ser executado na velocidade normal no Chrome, mesmo quando a guia não está ativa?
Preciso de desempenho ilimitado sob demanda para um jogo de navegador que usa o WebSockets, por isso sei por experiência própria que o uso do WebSockets não garante desempenho ilimitado, mas a partir de testes, a reprodução de um arquivo de áudio parece garantir
Aqui estão dois loops de áudio vazios que criei para esse fim. 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 reproduzo, sob demanda do usuário, com o Howler.js: https://github.com/goldfire/howler.js
É triste que não exista um método interno para ativar / desativar o desempenho completo do javascript por padrão; no entanto, os mineradores de criptografia podem seqüestrar todos os seus threads de computação usando Web Workers sem nenhum aviso: |
fonte
Eu liberei trabalhador de intervalo de pacote npm que setInterval e clearInterval implementação com o uso da Web de trabalho para manter em funcionamento em abas inativas para o Chrome, Firefox e IE.
A maioria dos navegadores modernos (Chrome, Firefox e IE), intervalos (temporizadores de janelas) são fixados para disparar não mais que uma vez por segundo em guias inativas.
Você pode encontrar mais informações sobre
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
fonte
Atualizei meu núcleo do jQuery para a versão 1.9.1 e resolveu a discrepância do intervalo nas guias inativas. Eu tentaria isso primeiro e depois procuraria outras opções de substituição de código.
fonte
aqui está minha solução que obtém o milissegundo atual e a compara com o milissegundo em que a função foi criada. por intervalo, ele atualizará o milissegundo quando executar a função. você também pode pegar o intervalo / tempo limite por um ID.
fonte