2011-07-05 10 views
9

Parece que ha habido un cambio en alguna versión reciente de Chrome y Firefox *, y ahora la ejecución de JavaScript parece ser diferente cuando la pestaña en la que se está ejecutando no está actualmente enfocada uno.Rendimiento de Javascript cuando se ejecuta en una pestaña desenfocada

Cuando ejecuto mis pruebas de unidad de Javascript, normalmente tardan unos 20 segundos en completarse, pero ahora, cuando la pestaña está desenfocada, demora más de 2000 segundos. Lo que es extraño, sin embargo, es que los tiempos de ejecución para cada prueba individual no se ven afectados (la mayoría todavía son < 10ms). El corredor de prueba que estoy usando agrega un setTimeout(0) entre ejecutar cada prueba para que el navegador no se bloquee durante la ejecución, y ese parece ser el culpable.

¿Hay alguna manera de decirle al motor de Javascript que no "despriorice" esa pestaña? Es agradable poder ejecutar mis pruebas en segundo plano sin tener que mirarme a mí mismo ...

* lo siento, realmente no me importa lo suficiente como para tratar de instalar versiones antiguas para encontrar cuándo esto comenzó a suceder. Por lo menos, está sucediendo ahora en Firefox 5.0 y Chrome 12.

Respuesta

9

setTimeout y setInterval haber sido estrangulado a un mínimo de 1000 ms en pestañas fuera de foco. Here es el informe de Bugzilla que lo menciona. Y aquí está el Chromium bug report similar. Creo que este es el caso en Firefox 5 y en Chrome desde la versión 11.

Según MDN:

En (Firefox 5.0/Thunderbird 5.0) y Chrome 11, los tiempos de espera se sujetan a disparando sin más de una vez por segundo (1000ms) en pestañas inactivas; vea error 633421 para obtener más información acerca de esto en Mozilla o crbug.com/66078 para detalles sobre esto en Chrome.

En cuanto a cómo superar esta restricción, puede probar la técnica que se analiza en this article, pero todavía no he tenido el cambio para probarla.

+0

Y: Para implementar un 0 ms de tiempo de espera en un navegador moderno puede usar 'window.postMessage()' https: //developer.mozilla. org/en/DOM/window.setTimeout – James

+0

@James - Publicaste tu comentario justo cuando actualicé mi respuesta con el artículo mencionado en esa página :) –

+0

¡Las grandes mentes piensan igual ... y tienen el mismo nombre! :) – James

2

El cambio realizado fue aumentar (por mucho) el valor mínimo de tiempo de espera. Que yo sepa, no hay forma de controlar eso; está en las entrañas de la implementación del temporizador. Tanto Chrome como Firefox hacen esto ahora, tal vez Safari también.

Se pone bastante extraño si usa "setInterval()", porque parece que el navegador quiere asegurarse de que la devolución de llamada de intervalo se llame el número de veces adecuado. Cuando regresas a la página, obtienes un estallido de actividad de los temporizadores de intervalo a medida que se ponen al día.

5

Para Firefox en particular, puede cambiar la preferencia dom.min_background_timeout_value en about:config a un número de su agrado en el perfil que utiliza para ejecutar las pruebas. Sin embargo, yo no recomendaría hacer eso en tu perfil de navegación predeterminado: la razón de la gran presión es que reduce los sitios web en pestañas de segundo plano masticando la CPU actualizando tontos tickers y cosas por el estilo.

0

pude solucionar utilizando setInterval múltiple():

var setRealInterval = function(callback, interval) { 
    var minBrowserInterval = 1000 
    var setIntervalsCount = Math.max(1, minBrowserInterval/interval) 
    for (var i = 0; i < setIntervalsCount; i++) { 
     ;(function(i) { 
      setTimeout(function() { 
       setInterval(callback, interval * setIntervalsCount) 
      }, i * interval) 
     })(i) 
    } 
} 
Cuestiones relacionadas