Antecedentes: estoy haciendo algunas pruebas de interfaz de usuario que necesitan detectar si las personas están prestando atención o no. Pero, esta pregunta no se trata de la API de visibilidad de la página .
Específicamente, me gustaría saber cómo se verá afectado mi código Javascript si la pestaña actual no está activa, o la ventana del navegador no está activa, en diferentes navegadores. He desenterrado lo siguiente hasta ahora:
- ios 5 pausa javascript cuando la pestaña no está activa
setInterval
y elsetTimeout
retraso se reduce cuando las pestañas no están activas ; parece que esto acaba de comenzar a aparecer recientemente y puede estropear las pruebas unitarias de Jasmine, en torno a otras cosas.requestAnimationFrame
se ralentiza cuando la pestaña no está activa (razonable, no puedo pensar por qué esto afectaría demasiado a alguien)
Tengo las siguientes preguntas:
- Además de los navegadores móviles, ¿los navegadores de escritorio pausan la ejecución de JS cuando una pestaña no está activa? ¿Cuándo y qué navegadores?
- ¿Qué navegadores reducen la
setInterval
repetición? ¿Se reduce a un límite o en un porcentaje? Por ejemplo, si tengo una repetición de 10 ms frente a una repetición de 5000 ms, ¿cómo se verá afectado cada uno? - ¿Se producen estos cambios si la ventana está desenfocada, en lugar de solo la pestaña? (Me imagino que sería más difícil de detectar, ya que requiere la API del sistema operativo).
- ¿Hay otros efectos que no se observarían en una pestaña activa? ¿Podrían estropear cosas que de otro modo se ejecutarían correctamente (es decir, las pruebas de Jasmine mencionadas anteriormente)?
javascript
browser
Andrew Mao
fuente
fuente
setInterval
/setTimeout
veces por debajo de 1000 ms se cambian a 1000 ms cuando la pestaña / ventana está borrosasetInterval
/setTimeout
times under 1000ms se cambian a 1000ms cuando la pestaña / ventana está borrosa. No está claro lo que ha intentado transmitirRespuestas:
Prueba uno
He escrito una prueba específicamente para este propósito:
Distribución de velocidad de cuadros: setInterval vs requestAnimationFrame
Nota: Esta prueba requiere bastante CPU.
requestAnimationFrame
no es compatible con IE 9 y Opera 12.La prueba registra el tiempo real que se necesita para una
setInterval
yrequestAnimationFrame
para funcionar en distintos navegadores, y le da los resultados en forma de una distribución. Puede cambiar el número de milisegundos parasetInterval
ver cómo se ejecuta en diferentes configuraciones.setTimeout
funciona de manera similar a asetInterval
con respecto a los retrasos.requestAnimationFrame
generalmente está predeterminado a 60 fps según el navegador. Para ver qué sucede cuando cambia a una pestaña diferente o tiene una ventana inactiva, simplemente abra la página, cambie a una pestaña diferente y espere un momento. Continuará registrando el tiempo real que lleva estas funciones en una pestaña inactiva.Prueba dos
Otra forma de probarlo es registrar la marca de tiempo repetidamente con
setInterval
yrequestAnimationFrame
y verlo en una consola separada. Puede ver con qué frecuencia se actualiza (o si alguna vez se actualiza) cuando desactiva la pestaña o ventana.setInterval
requestAnimationFrame
Resultados
Chrome
Chrome limita el intervalo mínimo de
setInterval
alrededor de 1000 ms cuando la pestaña está inactiva. Si el intervalo es superior a 1000 ms, se ejecutará en el intervalo especificado. No importa si la ventana está desenfocada, el intervalo se limita solo cuando cambia a una pestaña diferente.requestAnimationFrame
está en pausa cuando la pestaña está inactiva.https://codereview.chromium.org/6546021/patch/1001/2001
Firefox
Similar a Chrome, Firefox limita el intervalo mínimo de
setInterval
alrededor de 1000 ms cuando la pestaña (no la ventana) está inactiva. Sin embargo, serequestAnimationFrame
ejecuta exponencialmente más lento cuando la pestaña está inactiva, con cada cuadro tomando 1s, 2s, 4s, 8s y así sucesivamente.https://hg.mozilla.org/releases/mozilla-release/file/0bf1cadfb004/dom/base/nsGlobalWindow.cpp#l296
Internet Explorer
IE no limita el retraso
setInterval
cuando la pestaña está inactiva, pero se detienerequestAnimationFrame
en pestañas inactivas. No importa si la ventana está desenfocada o no.Edge
Comenzando desde Edge 14,
setInterval
tiene un límite de 1000 ms en pestañas inactivas.requestAnimationFrame
siempre está en pausa en pestañas inactivas.Safari
Al igual que Chrome, Safari se
setInterval
limita a 1000 ms cuando la pestaña está inactiva.requestAnimationFrame
está en pausa también.Opera
Desde la adopción del motor Webkit, Opera exhibe el mismo comportamiento que Chrome.
setInterval
tiene un límite de 1000 ms yrequestAnimationFrame
se detiene cuando la pestaña está inactiva.Resumen
Repetir intervalos para pestañas inactivas:
fuente
setInterval
yrequestAnimationFrame
?setInterval
yrequestAnimationFrame
. Lo que sé es que sesetTimeout
comporta de manera similarsetInterval
, ya que ambos tienen el mismo intervalo de fondo mínimo en Firefox y Chrome, y no tienen un límite aparente en otros navegadores.about:config
en el navegador y cambiando eldom.min_background_timeout_value
valor a algo más que 1000.requestAnimationFrame
se llama si el usuario simplemente cambia la aplicación (Alt + Tab fuera de Chrome). Mientras la pestaña esté activa en Chrome, la "velocidad de fotogramas" es más o menos constante.Lo que observé: en las pestañas inactivas en Chrome , todas sus esperas
setTimeout
(deben ser las mismas parasetInterval
) menos de 1000 ms se redondean a 1000 ms . Creo que los tiempos de espera más largos no se modifican.Parece ser el comportamiento desde Chrome 11 y Firefox 5.0 : https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout#Inactive_tabs
Además, no creo que se comporte de esta manera cuando toda la ventana está inactiva (pero parece bastante fácil de investigar).
fuente
focus
y losblur
eventos parecen detectar tanto los cambios de pestaña como de ventana, por lo que podría funcionar en ambos sentidos. Pero me pregunto cómo detecta la ventana si es realmente visible o no.Una respuesta más nueva para complementar estos: en Chrome 78.0.3904.108 Noto que todos estos tiempos de espera (no solo aquellos por debajo de 1000 ms) tardan un poco más de lo esperado cuando me muevo a una pestaña diferente, y luego vuelvo. El comportamiento que estoy viendo se describe más correctamente como "Todos los tiempos de espera en pestañas inactivas pueden retrasarse en una cantidad adicional, hasta un máximo de 1000 ms". :
fuente