Histórico: estou fazendo alguns testes na interface do usuário que precisam detectar se as pessoas estão prestando atenção ou não. Mas, essa pergunta não é sobre a API de visibilidade da página .
Especificamente, gostaria de saber como meu código Javascript será afetado se a guia atual não estiver ativa ou a janela do navegador não estiver ativa em diferentes navegadores. Eu desenterrei o seguinte até agora:
- O iOS 5 pausa o javascript quando a guia não está ativa
setInterval
e osetTimeout
atraso é reduzido quando as guias não estão ativas - parece que isso começou a aparecer recentemente e pode atrapalhar os testes de unidade do Jasmine, em torno de outras coisas.requestAnimationFrame
fica mais lento quando a guia não está ativa (razoável, não consigo pensar por que isso afetaria demais alguém)
Tenho as seguintes perguntas:
- Além dos navegadores móveis, os navegadores da área de trabalho pausam a execução de JS quando uma guia não está ativa? Quando e quais navegadores?
- Quais navegadores reduzem a
setInterval
repetição? É apenas reduzido a um limite ou a uma porcentagem? Por exemplo, se eu tiver uma repetição de 10 ms contra uma repetição de 5000 ms, como cada uma será afetada? - Essas mudanças acontecem se a janela estiver fora de foco, em vez de apenas a guia? (Imagino que seria mais difícil de detectar, pois requer a API do SO).
- Existem outros efeitos que não seriam observados em uma guia ativa? Eles poderiam atrapalhar coisas que seriam executadas corretamente (ou seja, os testes Jasmine mencionados)?
javascript
browser
Andrew Mao
fonte
fonte
setInterval
/setTimeout
vezes sob 1000ms são alterados para 1000 ms quando o separador / janela está borradasetInterval
/setTimeout
times abaixo de 1000ms são alterados para 1000ms quando a guia / janela está embaçada. Não está claro o que você tentou transmitirRespostas:
Teste Um
Escrevi um teste especificamente para esse fim:
Distribuição da taxa de quadros: setInterval vs requestAnimationFrame
Nota: Este teste é bastante intensivo da CPU.
requestAnimationFrame
não é suportado pelo IE 9- e Opera 12-.O teste registra o tempo real que leva para um
setInterval
erequestAnimationFrame
para executar em diferentes navegadores, e dá-lhe os resultados sob a forma de uma distribuição. Você pode alterar o número de milissegundos parasetInterval
ver como ele é executado sob diferentes configurações.setTimeout
funciona de maneira semelhante asetInterval
com relação a atrasos.requestAnimationFrame
geralmente o padrão é 60fps, dependendo do navegador. Para ver o que acontece quando você alterna para uma guia diferente ou tem uma janela inativa, basta abrir a página, alternar para uma guia diferente e aguardar um pouco. Ele continuará registrando o tempo real necessário para essas funções em uma guia inativa.Teste Dois
Outra maneira de testá-lo é registrar o registro de data
setInterval
e hora repetidamente comrequestAnimationFrame
e visualizá-lo em um console desanexado. Você pode ver com que frequência ela é atualizada (ou se alguma vez é atualizada) ao desativar a guia ou a janela.setInterval
requestAnimationFrame
Resultados
Chrome
Chrome limita o intervalo mínimo de
setInterval
cerca de 1000 ms quando a guia está inativa. Se o intervalo for maior que 1000ms, ele será executado no intervalo especificado. Não importa se a janela está fora de foco, o intervalo é limitado apenas quando você alterna para uma guia diferente.requestAnimationFrame
é pausado quando a guia está inativa.https://codereview.chromium.org/6546021/patch/1001/2001
Firefox
Semelhante ao Chrome, o Firefox limita o intervalo mínimo de
setInterval
cerca de 1000ms quando a guia (não a janela) está inativa. No entanto,requestAnimationFrame
é executado exponencialmente mais lento quando a guia está inativa, com cada quadro levando 1s, 2s, 4s, 8s e assim por diante.https://hg.mozilla.org/releases/mozilla-release/file/0bf1cadfb004/dom/base/nsGlobalWindow.cpp#l296
O Internet Explorer
IE não limita o atraso
setInterval
quando a guia está inativa, mas faz uma pausarequestAnimationFrame
nas guias inativas. Não importa se a janela está fora de foco ou não.Borda
A partir da borda 14, o
setInterval
limite é de 1000ms nas guias inativas.requestAnimationFrame
sempre é pausado em guias inativas.Safari
Assim como o Chrome, o Safari
setInterval
atinge os 1000ms quando a guia está inativa.requestAnimationFrame
também está em pausa.Opera
Desde a adoção do mecanismo Webkit, o Opera exibe o mesmo comportamento do Chrome.
setInterval
é limitado a 1000ms erequestAnimationFrame
pausado quando a guia está inativa.Resumo
Intervalos repetidos para guias inativas:
fonte
setInterval
erequestAnimationFrame
?setInterval
erequestAnimationFrame
. O que sei é quesetTimeout
se comporta de maneira semelhantesetInterval
, pois ambos têm o mesmo intervalo mínimo de segundo plano no Firefox e Chrome e nenhum limite aparente em outros navegadores.about:config
no navegador e mudar odom.min_background_timeout_value
valor para algo mais do que 1000.requestAnimationFrame
é chamado se o usuário simplesmente alternar entre aplicativos (Alt + Tab do Chrome). Enquanto a guia estiver ativa no Chrome, a "taxa de quadros" será mais ou menos constante.O que eu observei: nas guias inativas do Chrome , todas as suas
setTimeout
(devem ser iguaissetInterval
) a espera de menos de 1000ms são arredondadas para 1000ms . Penso que tempos limite mais longos não são modificados.Parece ser o comportamento desde o Chrome 11 e Firefox 5.0 : https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs
Além disso, acho que não se comporta dessa maneira quando a janela inteira está inativa (mas parece bastante fácil investigar).
fonte
focus
e osblur
eventos parecem detectar as opções de guia e janela, de modo que poderia funcionar nos dois sentidos. Mas eu me pergunto como a janela detecta se é realmente visível ou não.Uma resposta mais recente para complementar: no chrome 78.0.3904.108, percebo que todos esses tempos limite (não apenas aqueles abaixo de 1000ms) demoram um pouco mais do que o esperado quando eu mudo para uma guia diferente e depois volto. O comportamento que estou vendo é descrito mais corretamente como "Todos os tempos limites nas guias inativas podem sofrer um atraso adicional, em um valor adicional, até no máximo 1000ms". :
fonte