2010-04-22 13 views
5

Tengo una búsqueda que devuelve JSON, que luego transformo en una tabla HTML en Javascript. Llama repetidamente al método jQuery.append(), una vez para cada fila. Tengo una máquina moderna y el tiempo de respuesta de Firefox es aceptable. Pero en IE 8 es insoportablemente lento.¿Cuál es la forma más eficiente de administrar grandes conjuntos de datos con Javascript/jQuery en IE?

Decidí mover la transformación de datos a HTML en el lado del servidor PHP, cambiando el tipo de retorno de JSON a HTML. Ahora, en lugar de llamar a la hora jQuery.append() repetidamente, invoco el método jQuery.html() una vez con toda la tabla. Noté que Firefox se hizo más rápido, pero IE se volvió más lento.

Estos resultados son anecdóticos y no he hecho ninguna evaluación comparativa, pero el rendimiento de IE es muy decepcionante. ¿Hay algo que pueda hacer para acelerar la manipulación de grandes cantidades de datos en IE o simplemente es una mala idea procesar muchos datos a la vez con AJAX/Javascript?

Respuesta

9

Como otros han mencionado, la manipulación excesiva mata de DOM rendimiento. Crear una cadena HTML usando el Array.join ('') mencionado anteriormente y configurar el innerHTML de un contenedor usando el método jQuery.html() es mucho más rápido. Tenga cuidado con el uso de jQuery.append (html): ¡esto es equivalente a crear primero todos los nodos DOM y luego insertarlos!

Lo que pasa es que, incluso si optimiza la creación del árbol de nodos de página, todavía llegará a un techo bastante rápido con conjuntos de datos muy grandes. Los navegadores simplemente no pueden manejar árboles DOM tan grandes y complejos. Lo primero que verá ralentizar serán las interacciones (animaciones, manipuladores, etc.) incluso si usa la delegación de eventos. Si su conjunto de datos es realmente grande, necesitará hacer algún tipo de virtualización para mostrar solo lo que está visible en la ventana gráfica (esto es lo que hace SlickGrid - http://github.com/mleibman/slickgrid).

Como alternativa, puede mejorar la capacidad de respuesta y el "tiempo para interactuar" de su página agrupando sus adiciones DOM y ejecutándolas en un tiempo de espera una tras otra con una pausa intermedia para permitir que el navegador maneje los eventos del usuario.

Otras técnicas incluyen la representación de datos de la primera página, la asignación de espacio para más, pero solo la representación cuando el usuario comienza a desplazarse hacia ella. Esto es lo que hace Facebook.

+0

Tienes toda la razón. ... pero qué tan rápido es "¿estás en la ventana gráfica?" –

+0

Supongo que se refiere al control de la posición de desplazamiento. El cheque en sí es bastante rápido, especialmente si lo pones en un tiempo de espera pequeño. Eche un vistazo a los ejemplos de SlickGrid: la cuadrícula rinde 50.000 filas, pero es extremadamente rápida y receptiva. – Tin

+0

Acabo de terminar de implementar SlickGrid y es increíble. Es sin duda el plugin jQuery más poderoso que he usado, y me salvó de tener que rediseñar una gran parte de mi proyecto para tratar con IE. ¡Gracias! –

3

He hecho esto antes. Es toda la manipulación de DOM que ralentiza las cosas debido al proceso de repintado/reflujo que se activa después de cada adición.

Compilarlo como una cadena en el cliente, inserte la cadena en el DOM usando .html().

Esto ha funcionado con bastante éxito para mí, incluso en IE6.

+1

Es cierto: nunca obtendrás un gran rendimiento de IE (<9) con grandes conjuntos de datos, pero configurar innerHTML suele ser mucho más rápido que insertar un montón de nodos DOM con IE, sin importar el marco JS que puedas estar usando. –

1

Las operaciones de adición DOM múltiples matarán el rendimiento. Y también puede encontrarse con un problema con la inmutabilidad de las cuerdas.

Mantenga los datos lo más pequeños posible (los arreglos JSON son buenos) y cree el html en el script evitando el problema de concatenación de cadenas javascript. Agregue los valores html a una matriz, y luego únase a la matriz después. Haga un DOM agregar una vez que se ha creado el html. por ejemplo

var builder = []; 

//Inside a loop 
builder.push('<tr><td>'); 
builder.push(json.value); 
builder.push('</tr>'); 

//Outside the loop 
$('div').append(builder.join('')); 
0

Lo recomiendo enormemente la jQuery templating plugin,

He estado usando la función de micro-plantillas de John Resig durante unos meses. El plugin de plantillas es la evolución de eso. He estado escribiendo y presentando en ella durante todo el año :)

My Blog

Cuestiones relacionadas