2012-07-14 31 views
5

Estoy desarrollando una aplicación web .NET donde tengo que hacer peticiones ajax con la función javascript setInterval() para actualizar la información de algunas páginas.El uso de javascript setInvertal aumenta el consumo de memoria de la CPU

Con cada solicitud de Ajax recibo una respuesta xml de aproximadamente 68 KB que logro hacer cambios visuales en el html a través de jQuery. Establecí el intervalo en 2000 milisegundos, pero me gustaría, o mejor dicho, voy a necesitar reducirlo a 1000 ms.

Desafortunadamente, con cada solicitud aumenta el consumo de memoria de la CPU y esto provoca que el navegador se bloquee y el usuario no pueda usarlo a menos que vuelva a cargar la página. He probado esto en Firefox, Internet Explorer y Chrome, pero el resultado siempre es el mismo. Si no hago setInvertal(), el problema desaparecerá.

Además, he estado probando el alcance de todas mis variables de JavaScript pero no he encontrado nada incorrecto y supongo que Javascript tiene un recolector de basura eficiente para limpiarlas.

Espero haber explicado claro el problema. ¿Alguien tiene alguna idea para resolverlo?

Modificado: Estoy utilizando jQuery framework. Mi código es:

var tim; 
$(document).ready(function() { 
    tim = window.setInterval("refresh()", 2000); 
}); 

function refresh() { 
    $.post("procedures.aspx", $("#formID").serializeArray(), function (data) { 
    if (data != ""){ 
     var xml = $.parseXML(data); 

     ... (read and process xml to do changes in the html) 

    } 
    } 
} 
+1

Probablemente esté enfrentando alguna pérdida de memoria. Intenta restringir el problema al código más simple que causa este comportamiento (jsFiddle es bienvenido). –

+1

El bloque del navegador proviene del hecho de que los tiempos de espera/intervalos no funcionan, como a veces se cree, en un hilo dedicado. Si bien parece que claramente tiene un problema subyacente, puede haber un poco de kilometraje al buscar en los trabajadores de la web, lo que podría hacer lo que usted describe, y REALMENTE se ejecutan en un hilo separado. – Utkanos

+0

Por favor, publique una muestra de setInterval code –

Respuesta

5

No ha publicado ninguna fragmento de código para la inspección, por lo que mi respuesta se basa en un error comúnmente realizado al crear dichas funciones "votación". También estoy asumiendo que estás haciendo cosas manualmente, sin usar frameworks como jQuery o MooTools.

Su problema es más probable que sea causada por la creación de un nuevo objeto XMLHttpRequest en cada llamada de sondeo, en lugar de crear uno de esos casos fuera del setInterval, y abrir y usar el tiempo y otra vez.

Básicamente, usted puede estar escribiendo el código de la siguiente manera:

var pollInterval = setInterval(function() { 
    var xhr = new XMLHttpRequest(); //ouch, this hurts! 
    xhr.open('GET', 'url', true); 
    xhr.send(); 
    //etc. 
}, 2000); 

Si este es el caso, simplemente mover la creación XMLHttpRequestObject fuera del circuito de votación para asegurarse de que utiliza el mismo objeto una y otra vez, evitando así una pérdida de memoria de tipo (si puedo llamar así).

var xhr = new XMLHttpRequest(); //now we can re-use this! 
var pollInterval = setInterval(function() { 
    xhr.open('GET', 'url', true); 
    xhr.send(); 
    //etc. 
}, 2000); 


Una vez más, no se ha publicado ninguna fragmento de código, ni los detalles de los marcos que pueda estar usando. Entonces, lo que estoy sugiriendo está basado en un error que he encontrado frecuentemente al inspeccionar el código ajax de sondeo. Espero que esto ayude. Si no, edite la pregunta y publique un código.

Negación: Yo sólo se utiliza el objeto XMLHttpRequest para mayor brevedad, no sobre vendedores odio (o amor). Obviamente, utilizará una función de creación de instancias de objeto de solicitud entre navegadores o, mejor aún, una biblioteca que abstraiga estos detalles sangrientos.
 

Actualizaciones


Por lo tanto, el código necesita para actualizar el DOM cada dos segundos? ¿Mientras se cargue la página? ¿Nunca te detengas? Pensé que vería un intérvalo claro en alguna parte, pero de todos modos.

Esto es un poco incómodo.Lo más cerca que he estado de esa situación es cuando necesitaba codificar una línea de pulso, basada en un API de ticker, para mostrar un gráfico en tiempo real (ok, pseudo-tiempo real a 1s). Lo bueno de mi caso fue que la API estaba ardiendo rápidamente, con una latencia súper baja, los datos que recibí eran meramente flotantes, y la manipulación dom que hice con ella era de insignificante complejidad espacio-tiempo.

Mi preocupación aquí es que si el servidor no responde en dos segundos, o si se acerca a dos segundos, entonces tiene un fragmento de código complejo que ya está comiendo en milisegundos significativos de esos dos segundos intervalos. ¡Dom no puede actualizar cada dos segundos!

  1. punta higiénico: Deshacerse de las cotizaciones en window.setInterval("refresh()", 2000). Sólo debe ser window.setInterval(refresh, 2000) Las razones son aquí: Memory leak for javascript setInterval

  2. Así, $ .post definitivamente crear nuevos objetos XHR cada dos segundos, según el código. Siendo realistas, ¿cómo son los tiempos de respuesta del servidor ? ¿Cuántas veces establece setInterval loop? Para recuentos bajos, por ejemplo, para tiempos de respuesta inferiores a 10 segundos, los nuevos XHR no deberían ser el problema 'EL' .

  3. ¿Analizar 500 líneas XML? Cada intervalo? Suena doloroso para mí. ¿Será posible ser tokenize el XML en una cadena JSON en el servidor y devolver esta cadena a la UI? Ahorrará los ciclos de la CPU del cliente con seguridad.

HTML con 11000 líneas. Así que eso es mucho cruce y manipulación. Aquí hay una pequeña lista de verificación:

  1. ¿Está utilizando los mejores selectores? (especificidad de tus expresiones xpath). Shizzle te tiene cubierto allí, pero hazlo lo mejor que puedas. Cosas como $ ('p *') pueden causar estragos.

  2. ¿Ha minimizado el reflujo de documentos?

  3. Loops: El uso de, o asignada funciones sobre las matrices son los mejores (más eficiente)

  4. Acceso a la propiedad: ¿Está reduciendo el acceso repetido propiedad anidada , y el uso de una sola vez las referencias para la eficiencia ?

  5. Anexión/Manipulación de la eficiencia: Por ejemplo: Cómo se anexa elementos individuales de la lista? Lo ideal es agregar toda la lista en una sola vez. Lo mismo para eliminaciones, etc. Básicamente, gruesas manipulaciones de una sola vez en lugar de manipulaciones repetidas.

Difícil de clavar éste, sin entender las intenciones de bajo nivel y la mecánica de su caso de uso.

+0

Ya he publicado mi código. Entiendo perfectamente tu respuesta, pero no sé si el comportamiento de jQuery cuando crea los objetos XMLHttpRequest es el correcto (supongo que sí). – jbernal

+0

Es razonable suponer que $ .post creará un nuevo objeto XHR cada vez, de lo contrario, considere el caso de dos sentencias $ .post una tras otra. Cada uno es asíncrono y puede regresar en diferentes momentos. Sería desastroso si las dos llamadas usaran el mismo objeto XHR debajo del capó. Así que eso es para empezar: un nuevo XHR cada dos segundos. –

+0

Muchas gracias por su respuesta rápida y completa, realmente lo aprecio. Mi aplicación debe monitorear un sistema importante de una gran empresa, donde los usuarios deben conocer el estado de una gran cantidad de componentes y variables en tiempo real. Por esta razón, mi xml tiene muchas líneas, porque hay muchas variables para monitorizar. No me gustan las 11000 líneas html, pero es un requisito, toda la información debe estar en la página cargada. Hasta donde sé, mientras la página está cargada, la actualización no puede detenerse y la página puede cargarse durante horas (incluso hasta 8 horas). – jbernal

1

Finalmente, he resuelto este problema. En general, la solución principal ha sido cambiar el servidor de respuesta a JSON. Reduje mi respuesta hasta 4 KB.

Además, he sido más preciso manipulando y agregando elementos html al DOM.

Ahora, la aplicación web puede funcionar durante horas y todo funciona bien.

Cuestiones relacionadas