La aparición de AJAX ha cambiado enormemente el modo de funcionamiento de los clientes de aplicaciones web. Permite a los usuarios concentrarse en su trabajo sin tener que soportar las molestas actualizaciones de página con frecuencia. En teoría, la tecnología AJAX puede reducir en gran medida el tiempo de espera para las operaciones del usuario y ahorrar tráfico de datos en la red. Sin embargo, este no es siempre el caso. Los usuarios suelen quejarse de que se reduce la velocidad de respuesta de los sistemas que utilizan AJAX.
El autor ha estado involucrado en la investigación y el desarrollo de AJAX durante muchos años y participó en el desarrollo de Dorado, una plataforma AJAX relativamente madura en China. Según la experiencia del autor, la causa principal de este resultado no es AJAX. Muchas veces la reducción en la velocidad de respuesta del sistema se debe a un diseño de interfaz poco razonable y a hábitos de programación insuficientemente eficientes. A continuación analizaremos varios aspectos a los que se debe prestar atención durante el proceso de desarrollo de AJAX.
Uso adecuado de la programación del cliente y llamadas a procedimientos remotos.
La programación del lado del cliente se basa principalmente en JavaScript. JavaScript es un lenguaje de programación interpretado y su eficiencia operativa es ligeramente menor que la de Java. Al mismo tiempo, JavaScript se ejecuta en un entorno estrictamente restringido como el navegador. Por lo tanto, los desarrolladores deben tener una comprensión clara de qué lógica se puede ejecutar en el lado del cliente.
La forma en que se debe utilizar la programación del lado del cliente en aplicaciones reales depende de la experiencia y el criterio del desarrollador. Muchos problemas aquí sólo pueden entenderse. Debido al espacio limitado, aquí resumimos aproximadamente las siguientes precauciones:
Evite el uso frecuente de llamadas a procedimientos remotos tanto como sea posible; por ejemplo, evite el uso de llamadas a procedimientos remotos en cuerpos de bucle.
Si es posible, utilice la llamada a procedimiento remoto AJAX (llamada a procedimiento remoto asíncrona).
Evite colocar operaciones de datos pesadas en el lado del cliente. Por ejemplo: grandes lotes de operaciones de copia de datos, cálculos que requieren un gran recorrido de datos, etc.
Mejorar el método de operación de los objetos DOM.
En la programación del lado del cliente, las operaciones en objetos DOM suelen ser las que ocupan más tiempo de CPU. Para la operación de objetos DOM, la diferencia de rendimiento entre diferentes métodos de programación suele ser muy grande.
Los siguientes son tres fragmentos de código con exactamente los mismos resultados. Su función es crear una tabla de 10x1000 en la página web. Sin embargo, sus velocidades de carrera son muy diferentes.
/* Código de prueba 1 - Tiempo necesario: 41 segundos*/
var tabla = document.createElement("TABLA");
documento.body.appendChild(tabla);
para(var i = 0; i < 1000; i++){
var fila = table.insertRow(-1);
para(var j = 0; j < 10; j++){
var celda = objRow.insertCell(-1);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* Código de prueba 2 - Tiempo necesario: 7,6 segundos*/
var tabla = document.getElementById("TABLA");
documento.body.appendChild(tabla);
var tbody = document.createElement("TBODY");
tabla.appendChild(tbody);
para(var i = 0; i < 1000; i++){
var fila = document.createElement("TR");
tbody.appendChild(fila);
para(var j = 0; j < 10; j++){
var celda = document.createElement("TD");
fila.appendChild(celda);
cell.innerText = "( " + i + " , " + j + " )";
}
}
/* Código de prueba 3 - tiempo necesario: 1,26 segundos*/
var tbody = document.createElement("TBODY");
para(var i = 0; i < 1000; i++){
var fila = document.createElement("TR");
para(var j = 0; j < 10; j++){
var celda = document.createElement("TD");
cell.innerText = "( " + i + " , " + j + " )";
fila.appendChild(celda);
}
tbody.appendChild(fila);
}
var tabla = document.getElementById("TABLA");
tabla.appendChild(tbody);
documento.body.appendChild(tabla);
La diferencia entre el "Código de prueba 1" y el "Código de prueba 2" aquí es que se utilizan diferentes métodos API al crear celdas de tabla. La diferencia entre el "Código de prueba 2" y el "Código de prueba 3" radica en el orden de procesamiento ligeramente diferente.
No podemos analizar una diferencia de rendimiento tan grande entre el "Código de prueba 1" y el "Código de prueba 2". Lo que se sabe actualmente es que insertRow e insertCell son API específicas de tablas en DHTML, y createElement y appendChild son API nativas de W3C DOM. El primero debería ser una encapsulación del segundo. Sin embargo, no podemos concluir de esto que la API nativa del DOM sea siempre mejor que la API específica de objeto. Se recomienda realizar algunas pruebas básicas sobre su rendimiento cuando necesite llamar a una API con frecuencia.
La diferencia de rendimiento entre el "Código de prueba 2" y el "Código de prueba 3" proviene principalmente de la diferencia en su orden de compilación. El enfoque del "Código de prueba 2" es crear primero el objeto
en secuencia en el bucle. El enfoque del "Código de prueba 3" es primero construir la tabla completa en la memoria desde adentro hacia afuera y luego agregarla a la página web. El propósito de esto es reducir al máximo la cantidad de veces que el navegador recalcula el diseño de la página. Cada vez que agregamos un objeto a una página web, el navegador intenta recalcular el diseño de los controles en la página. Por lo tanto, si primero podemos crear el objeto completo que se construirá en la memoria y luego agregarlo a la página web de una vez. Luego, el navegador solo volverá a calcular el diseño. Para resumirlo en una oración, cuanto más tarde ejecute appendChild, mejor. A veces, para mejorar la eficiencia operativa, incluso podemos considerar usar removeChild para eliminar el control existente de la página y luego volver a colocarlo en la página una vez que se complete la construcción. Mejorar la velocidad de acumulación de cadenas Cuando uso AJAX para enviar información, es posible que a menudo necesite ensamblar algunas cadenas relativamente grandes para completar el envío POST a través de XmlHttp. Aunque enviar una cantidad tan grande de información pueda parecer poco elegante, a veces podemos tener que afrontar esa necesidad. Entonces, ¿qué tan rápida es la acumulación de cadenas en JavaScript? Hagamos primero el siguiente experimento. Acumule una cadena de longitud 30000. /* Código de prueba 1 - Tiempo necesario: 14,325 segundos*/ var cadena = ""; para (var i = 0; i < 50000; i++) { cadena += "xxxxxx"; } Este código tardó 14,325 segundos y los resultados no fueron los ideales. Ahora cambiamos el código a la siguiente forma: /* Código de prueba 2 - Tiempo necesario: 0,359 segundos*/ var cadena = ""; para (var i = 0; i < 100; i++) { var sub = ""; para (var j = 0; j < 500; j++) { sub += "xxxxxx"; } cadena += sub; } ¡Este código tarda 0,359 segundos! El mismo resultado, todo lo que hacemos es ensamblar algunas cadenas más pequeñas primero y luego ensamblar cadenas más grandes. Este enfoque puede reducir efectivamente la cantidad de datos copiados en la memoria en las últimas etapas del ensamblaje de cadenas. Después de conocer este principio, podemos desmantelar aún más el código anterior para realizar pruebas. El siguiente código solo toma 0,140 segundos. /* Código de prueba 3 - Tiempo necesario: 0,140 segundos*/ var cadena = ""; para (var i1 = 0; i1 < 5; i1++) { var cadena1 = ""; para (var i2 = 0; i2 < 10; i2++) { var cadena2 = ""; para (var i3 = 0; i3 < 10; i3++) { var cadena3 = ""; para (var i4 = 0; i4 < 10; i4++) { var cadena4 = ""; para (var i5 = 0; i5 < 10; i5++) { cadena4 += "xxxxxx"; } cadena3 += cadena4; } cadena2 += cadena3; } cadena1 += cadena2; } cadena += cadena1; } Sin embargo, ¡el enfoque anterior puede no ser el mejor! Si la información que necesitamos enviar está en formato XML (de hecho, en la mayoría de los casos, podemos intentar ensamblar la información que se enviará en formato XML), también podemos encontrar una forma más eficiente y elegante: usar objetos DOM para ensamblar. caracteres para nosotros cadena. El siguiente párrafo solo toma 0,890 segundos para ensamblar una cuerda con una longitud de 950015. /* Utiliza objetos DOM para reunir información - tiempo necesario: 0,890 segundos*/ var xmlDoc; si (tipo de navegador == NAVEGADOR_IE) { xmlDoc = nuevo ActiveXObject("Msxml.DOMDocument"); } demás { xmlDoc = documento.createElement("DOM"); } var raíz = xmlDoc.createElement("raíz"); para (var i = 0; i < 50000; i++) { var nodo = xmlDoc.createElement("datos"); si (tipo de navegador == NAVEGADOR_IE) { nodo.text = "xxxxxx"; } demás { nodo.innerText = "xxxxxx"; } root.appendChild(nodo); } xmlDoc.appendChild(raíz); var str; Evite pérdidas de memoria de objetos DOM. |