Contenido

La optimización definitiva de WordPress

17 nov

+ 7

Hay que reconocer que aunque WordPress es un buen software tiene una serie de puntos débiles que hacen que trabajar con él nos dé más de un dolor de cabeza. Entre los problemas que más detectamos es el excesivo consumo de memoria y de recursos en general que necesita para funcionar eficazmente. En estos casos, lo mejor es, sin duda, optimizar todo lo que WordPress necesita para funcionar, desde el servidor web hasta el servidor de base de datos pasándo por las imágenes que servimos y el javascript que le hacemos llegar al usuario. Con esta guía podrás optimizar al milímetro cualquier aspecto de la instalación de tu WordPress.

Rendimiento extremo de Javascript

10 nov

+ 10

En uno de esos momento de querer pulir scripts en Javascript me pegó la neura de probar diferente formas de hacer lo mismo sacando el cronómetro y midiendo tiempos para ver que era más eficiente y que lo era menos.

Al final, por esas cosas del destino, me tuve que ir al final terminé olvidándome de lo que quería hacer. Hasta ahora que me he encontrado con esta presentación de Thomas Fuchs (author de Script.aculo.us). En ella (la recomiendo) hace exáctamente lo que yo quería hacer, medir los tiempos de ciertas tareas cotidianas y compararlas con alternativas que nos ofrece el mismo resultado.

Algunos de los resultados muestran cosas realmente interesantes:

Rendimiento

Objetos literales frente a clásicos

// Más lento
function literals(){
 var a = [], o = {};
}
// Más rápido
function classic(){
 var a new Array, o = new Object:
}

En la presentación se ven los resultados sobre los diferentes navegadores y podemos ver como de usar uno u otro en Google Chrome podemos multiplicar por 2 el tiempo de proceso.

Loops

Los loops tambien muestran unos resultados curiosos:

var test = '';
for (var i = 0; i<10000; i++)
 test = test + str;

var test = '', i = 10000;
while(i--) test = test + str;

Entre los dos anteriores, no se muestran diferencias en los resultados devueltos.

// Más lenta
function normalLoop(){
 var i = 60, j = 0;
 while(i--) j++;
}

// Más rápida
function unrolledLoop(){
 var j = 0;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
 j++; j++; j++; j++; j++; j++;
}

Tambien vemos que muy caro hacer un loop, en Firefox multiplicamos por 2 el tiempo y en Google Chrome lo multiplicamos por 5.

Cachear variables globales

// Más rádida
function cache(){
 var w = window, i = 10000;
 while(i--) w.test = 'test';
}

// Más lenta
function nocache(){
 var i = 10000;
 while(i--) window.test = 'test';
}

El cachear variables globables nos ayudará en la mayoría de casos.

Acceder a atributos de un objeto frente a with()

// Más lento
function conwith(){
 var obj = { prop: 'test', str: '' };
 with(obj){
 var i = 10000;
 while(i--) str += prop;
 return str;
 }
}

// Más rápido
function sinwith(){
 var obj = { prop: 'test', str: '' }, i = 10000;
 while(i--) obj.str += obj.prop;
 return obj.str;
}

En los resultados nos muestra que usar with() para acceder a un objeto nos puede penalizar el tiempo de proceso de nuestro Javascript. En el caso de Google Chrome reducimos el tiempo a un 7% del empleado con with().

Pasar a bits frente a parseInt()

// Más lenta
parseInt(12.50);

// Más rápida
~~(1 * "12.5");

Javascript 1.5 integra una serie de operadores a nivel de bit, entre ellos nos encontramos ~(Alt Gr + 4) que representa el NOT a nivel de bit y que en este caso nos ayuda a convertir a entero una cadena como podemos ver en el ejemplo (haciendo un doble NOT para obtener un valor positivo).

Curiosidades del lenguaje

Diferencia entre && y ||

var n = 1;
if (true && (n=2)) ...;
console.log(n);
// --> n = 2
if (true || (n=3)) ...;
console.log(n);
// --> n = 2

Como es lógico, el uso de && evalua las dos condiciones frente a || que si ya se cumple la primera, nos evitamos comprobar la segunda.

(...).toString()

(function(){ return 2 * 3; }).toString();

// IE, Safari y Google Chrome
function(){ return 2 * 3; }

// Firefox
function(){ return 6; }

En este ejemplo vemos como la ejecución de esta función anónima nos muestra un resultado algo extraño en Firefox.

Más info

  1. Extreme Javascript Perfomance (Thomas Fuchs)
  2. JsRocks

Acelerándo la carga de Javascript con eval()

28 oct

+ 16

En el blog de SproutCore publican un interesante artículo sobre como mejorar el tiempo de carga de nuestras páginas al usando eval(). Es por todos conocidos las anomalías con las que nos encontramos al usar esta función del lenguaje,  pero en algunos casos, puede ayudarnos a mejorar la carga de nuestras páginas.

Okito, nos comenta que la inspiración le llegó al revisar como Gmail gestionaba el Javascript de la página en su versión móvil, usándo un sistema de carga asíncrona que posteriormete es parseada con regexp y evaluada con eval().

En la versión 1.0 de SproutCore han implementado esta técnica y presume una mejora de 8 segundos en una aplicación de prueba sobre Internet Explorer.

El problema

El problema radica en que las aplicaciones muy ricas en Javascript suelen ser muy pesadas para el procesador y el navegador, despues de descargar el JS, parsear el script lo ha de evaluar (internamente) para poner a nuestra disposición todas las funcionalidades que hayamos desarrollado, en este último punto es donde más se penaliza la ejecución de JS (hasta un 80% del tiempo de carga total).

La propuesta

Para solventar el problema, nos propone cargar el Javascript de una forma diferente, en lugar de código usar comentarios. Osea, hacer que todo el código Javascript sea un gran comentario.

/*
function mifuncion(){
....
}

var lala = mifuncion();
lala.prototype.bla = function(){
 ...
}

....
*/

Explicación

Al tratarse de un comentario el navegador no lo evalua y nos ahorramos un tiempo de carga muy valioso y podemos hacer que la carga del código sea cosa nuestra haciendo uso únicamente de él cuando lo necesitemos. Esto nos permite tener un control sobre el Javascript que está ejecutado en todo momento.

quick_test_data-20091027-145104
(Ver Imagen)

Como vemos en el gráfico, la evaluación de comentarios es ligeramente menor a la de una cadena de texto y muy menor a la de funciones.

En dispositivos móviles este tiempo parece más significativo como podemos ver en la imagen siguiente:

quick_test_data_-_iphone-20091027-142630
(Ver Imagen)

Implementándolo

<html>
[...]
<!-- Javascript que será ejecutado posteriormente -->
<script id="lazy">
/*
Código Javascript
*/
</script>
[...]
<script>
 // Función encargada de recoger el contenido del <script id="lazy" /> y evaluarlo
 function lazyLoad() {
 var lazyElement = document.getElementById('lazy');
 var lazyElementBody = lazyElement.innerHTML;
 var jsCode = lazyElementBody.replace(/(\/\*|\*\/)/g,''); // Eliminamos (/*|*/)
 eval(jsCode);
 }
</script>
[...]
<!-- Activamos la carga del JS al hacer click-->
<div onclick=lazyLoad()> Lazy Load </div>
</html>

Como vemos en el código, el sistema básicamente lo que hace es cargar el javascript como un tag con un el código Javascript comentado completamente por lo que el navegador lo omitirá en el momento de evaluarlo.

lazyLoad() se encarga de coger el innerHTML del elemento que hemos cargado previamente con el javascript comentado, elimina los carácteres que indica que sea un comentario (en el ejemplo elminará todos los carácteres /* y */ del innerHTML, por que hay que usarlo con cabeza) y posteriormente lo evalua con eval().

Resultado

La ventaja de este sistema es que nos permite ejecutar ese código cuando queremos y no cuando está cargando la página, mayor control y sobretodo mayor velocidad global de la aplicación.

En los ejemplo de SproutCore obtienen una mejoría de entre 3x y 20x frente a la versión de carga secuencial de Javascript.

Optimizando, que es gerundio

Gerardo hace una puntualización en un comentario que me hace rectificar. Como en el 100% de los casos las expresiones regulares son más lentas que las funciones nativas de los objetos Javascript. En este caso, hacer un substring() nos hace reducir el tiempo de carga considerablemente.

Primero he hecho una prueba con HTML y cargando un fichero JS pesado, he usado Ext.js (versión comprimida 130kb) y he hecho una carga limpia del fichero.

ext.js
(Ver Imagen)

Vemos el tiempo de carga del fichero Javascript acercándose a los 4 segundos. Y despues he hecho una quitando la llamada al fichero externo y lo he añadido como comentario en el HTML.

ext.js-enHTML
(Ver Imagen)

El tiempo de carga se reduce considerablemente. Pero este tiempo es únicamente el que tarda el navegador en recibir el fichero no tiene en cuenta el tiempo de ejecución del mismo.

Por otro lado he hecho pruebas de uso entre replace() y substring().

Código

// Versión usando replace
function conreplace(){
 var el = document.getElementById("lazy");
 var text = el.innerHTML;
 jsCode = text.replace(/(\/\*|\*\/)/g,'');
 eval(jsCode);
 }

 // Versión usando substring
 function consubstring(){
 var el = document.getElementById("lazy");
 var text = el.innerHTML;
 var ini = text.indexOf("/*") + 2;// 2 == "/*".length
 var fin = text.lastIndexOf("*/");
 jsCode = text.substring(ini , fin);
 eval(jsCode);
 }

Resultados

  • Replace: 322ms.
  • SubString: 159ms.

Obviamente el replace elimina más comentarios del código que el subString, pero para este caso no necesitamos complicarnos más. Dejo el ejemplo optimizando a continuación.

<html>
[...]
<!-- Javascript que será ejecutado posteriormente -->
<script id="lazy">
/*
Código Javascript
*/
</script>
[...]
<script>
 // Función encargada de recoger el contenido del <script id="lazy" /> y evaluarlo
 function lazyLoad() {
 var lazyElement = document.getElementById('lazy');
 var lazyElementBody = lazyElement.innerHTML;
 var ini = lazyElementBody.indexOf("/*") + "/*".length;
 var fin = lazyElementBody.lastIndexOf("*/");
 jsCode = lazyElementBody.substring(ini , fin); // Eliminamos (/*|*/)
eval(jsCode);
}
</script>
[...]
<!-- Activamos la carga del JS al hacer click-->
<div onclick=lazyLoad()> Lazy Load </div>
</html>

Estos pequeños detalles son intersantes a tener en cuenta.

Diferentes formas de optimizar el consumo de memoria de WordPress a prueba

10 sep

+ 17

Hace un par de días hablabamos de una forma de mejorar el consumo de memoria de tu WordPress. La solución, usar eAccelerator junto a Zend Optimizer permitía mejorar hasta un 90% el consumo de memoria consumida.

Aprovechando que MAMP tiene un sistema fácil y cómodo de probar estas combinaciones he hecho una prueba con un blog limpio recien instalado con diferentes combinación, los resultados son realmente interesantes.

Test

Partimos de que estoy en un iMac con 2GB de RAM, bajo Leopard. La versión de MAMP disponde de :

Las pruebas las he realizado sobre la versión PHP5 (osea la 5.2.3) con 32 MB de límite de memoria. Y los componentes que he testeado son:

Mediante un simple panel de la propia aplicación hacer los cambios es tan sencillo como seleccionar la combinación y pulsar aceptar.

panel-MAMP
(Ver Imagen)

Continua —>

La mejora manera de cargar javascript

31 jul

+ 26

Hace unos meses vimos algunas técnicas para cargar Javascript asincronamente y así evitar el bloqueo del navegador mientras se carga el fichero Javascript. El mayor problema que nos encontramos al cargar Javascript es que el navegador deja de renderizar la página mientras carga el fichero Javascript.

En cambio, si cargamos los ficheros dinámicamente mediante Javascript, evitamos el problema y podemos cargar ficheros Javascript de forma asíncrona sin afectar al renderizado de la página.

Nicholas C. Zakas, ha estado pensando sobre el tema y ha sacado 3 puntos imprescindibles a tener en cuenta para mejorar la carga del javascript de nuestras páginas.

  1. Crear dos ficheros Javascript. En el primero poner lo necesario para cargar dinámicamente otro ficheros javascript y el segundo con el código necesario para nuestra aplicación.
  2. Incluye el primer Javascript el final de la página, justo encima de </body>.
  3. Justo debajo creamos un segundo tag <script> en donde llamaremos al/los fichero/s necesarios.

Nuestro HTML quedaría más o menos así:

<script type="text/javascript" src="http://your.cdn.com/first.js"></script>
<script type="text/javascript">
loadScript("http://your.cdn.com/second.js", function(){
 //initialization code
});
</script>

loadScript()

loadScript() es la función encargada de cargar el fichero Javascript de forma dinámica y encargada de ejecutar el código que indiquemos como segundo parámetro en cuando este esté cargado correctamente.

function loadScript(url, callback){

 var script = document.createElement("script")
 script.type = "text/javascript";

 if (script.readyState){  //IE
    script.onreadystatechange = function(){
     if (script.readyState == "loaded" ||
         script.readyState == "complete"){
           script.onreadystatechange = null;
           callback();
        }
     };
 } else {  //Others
   script.onload = function(){
     callback();
   };
 }

 script.src = url;
 document.getElementsByTagName("head")[0].appendChild(script);
}

Está claro que estas optimizaciones mejoran el resultado, aunque estamos hablando de milisegundos (o pocos segundos en el peor de los casos). Pero es bueno conocer formas de mejorar nuestros scripts y así pulirlos perfectamente.

Baja tus scripts al final del fichero

30 jun

+ 23

Una de las técnicas más usadas para reducir el tiempo de carga de una página web es la de bajar el Javascript al final del fichero HTML, concretamente justo encima de </body>.

Esto hace que la carga de la página, no se quede en stand-by mientras termina de cargar el javascript. El resultado es realmente sorprendente:

Antes:

beforenet
(Ver Imagen)

Despues:

afternet
(Ver Imagen)

Conclusión

Como podemos ver hemos reducido un 47% el tiempo de carga de la página (la del ejemplo) o hemos mejorado el tiempo de carga un 210%, haciendo que esta cargue en casi la mitad de tiempo.

Esto además, nos evita problemas con el evento onload ya que los elementos HTML ya están añadidos al árbol DOM.

for reverso para grandes interaciones en Javascript

28 may

+ 20

Luigi, me muestra hoy un artículo muy interesante sobre optimización de Javascript. En él encontramos un ejemplo de como mejorar nuestras iteraciones en nuestro código. Simplemente debemos pensar en decrementar la variable que estamos iterando. He montado un pequeño ejemplo para testear 50.000, 500.000 y 5.000.000 de iteraciones simples. Los resultados hablan por si solos:

[increment]50.000 iteraciones: 11ms. (50000)
[decrement]50.000 iteraciones: 2ms. (50000)
[increment]500.000 iteraciones: 115ms. (500000)
[decrement]500.000 iteraciones: 19ms. (500000)
[increment]5.000.000 iteraciones: 1188ms. (5000000)
[decrement]5.000.000 iteraciones: 181ms. (5000000)

Funciones

El código del ejemplo es muy sencillo y como se puede ver, únicamente se encarga de incrementar la variable y, en ambas.

	var fors = {
		increment: function(iterations){
				var y = 0;
				for (var i=0;i<iterations;i++){
					y++;
				}
				return y;
		},
		decrement:function (iterations){
			var y = 0;
			for (var i=iterations;i>0;i--){
				y++;
			}
			return y;
		}
	}

Como podemos ver, un pequeño cambio puede significar reducir entre un 200 y un 600% el tiempo de procesamiento de nuestros scripts. ¿Alguna optimización más?

Explicación

El motivo de esta diferencia de tiempo, es debido a que increment() debe realizar una revisión del valor de iterations por cada pasada por el bucle. De esta forma, se realiza un acceso a memoria para solicitar el valor de la variable, algo que no pasa en decrement() que al comparala con 0, nos ahorramos dicha consulta.

actuR.com, optimizador de código

20 may

+ 7

Carlos Sanches me avisa via email sobre la nueva aplicación en la que ha estado trabajando. acutR.com, un optimizador de código que nos permite desde optimizar código HTML hasta minimizar nuestro código CSS. Muy recomendable para ahorrarnos esos minutos de depuración :D

No uses @import

9 abr

+ 10

¿Que momento sería mejor para optimizar nuestros CSS que el día en el que no tenemos ninguno cargado? Steven Souders publica hoy un interesante artículo en el que nos aconseja no usar la propiedad @import del CSS y nos invita a mejorar el rendimiento de nuestras páginas mediante el tag <link />.

<link /> versus @import

Existen dos formas de cargar hojas de estilos (CSS) mediante HTML. Las dos funcionan de formas diferentes para conseguir un mismo objetivo, cargar un fichero .css y darle color y forma a nuestro contenido.

<link />

Se trata de un tag que los estándares web indican que debe ir declarado entre los tags <head />, este tag indica una relación con un documento externo. Con él, indicamos los ficheros RSS, los favicon y por supuesto, las hojas de estilos.

Para ello, hacemos uso del atributo rel, y posteriormente mediante el atributo href indicamos la ubicación del fichero que relacionamos directamente con el HTML. También es interesante destacar el atributo media, que indica que dispositivos van a poder usar ese documento.

<link rel='stylesheet' href='a.css' media='screen'>

@import

Se trata de una funcionalidad del CSS que nos permite cargar un fichero .css desde el propio CSS. Al igual que el anterior, con ella podemos indicar la ruta y el tipo de dispositivo que podrá usar ese código CSS.

Esta funcionalidad omite el atributo rel, debido a que se ha de llamar desde el tag <style /> o desde un fichero .css, entendiéndose así que se ha de tratar de un fichero CSS.

<style type="text/css">
	@import url('a.css') screen;
</style>

¿Cual es mejor?

Steve Souders, nos muestra mediante un pequeño test las diferentes opciones posibles que ha usado para ilustrar su prueba.

@import @import

<style>
@import url('a.css');
@import url('b.css');
</style>

En la prueba que opta por cargar dos fichero .css mediante la @import vemos como ambos ficheros cargan a la vez. Si generalmente usas este sistema, no deberías tener problemas de rendimiento ya que ambas peticiones se ejecutan simultáneamente evitando tiempos de espera innecesarios.

<link /> @import

<link rel='stylesheet' type='text/css' href='a.css'>
<style>
@import url('b.css');
</style>

Si por el contrario usas este sistema, todas las versiones de Internet Explorer (6,7 y 8)  harán que los ficheros se carguen secuencialmente así que primero se cargará a.css y cuando este termine comenzará b.css.

<link /> con @import

//HTML
<link rel='stylesheet' type='text/css' href='a.css'>

//CSS
@import url('b.css');

Entendamos que el fichero a.css, contiene la llamada al fichero b.css. De esta forma no solo ocurre en Internet Explorer, sino que la carga se convierte secuencial en todos los navegadores. Tiene sentido ya que cargamos a.css y una vez cargado lo procesamos y este nos llama a b.css.

varios <link /> @import

//HTML
<link rel='stylesheet' type='text/css' href='a.css'>
<link rel='stylesheet' type='text/css' href='proxy.css'>

//PROXY.CSS
@import url('b.css');

Mediante este sistema, descubrimos que Internet Explorer se vuelve loco. Únicamente en Internet Explorer, carga el fichero a.css y simultáneamente comienza a cargar el fichero proxy.css (que únicamente tiene la llamada a b.css), una vez terminado el fichero proxy.css este se queda esperando a que termine a.css para lanzar la llamada a b.css. Mejor ver la imagen.

link-blocks-import
(Ver Imagen)

muchos @import

<style>
@import url('a.css');
@import url('b.css');
@import url('c.css');
@import url('d.css');
@import url('e.css');
@import url('f.css');
</style>
<script src='one.js' type='text/javascript'></script>

Misteriosamente Internet Explorer vuelve a hacer de las suyas, en este caso, el fichero Javascript se carga antes que los ficheros .css, haciendo que toda relación con las posibles sentencias CSS no sean tratadas en el momento de la carga. A la vez que carga el fichero javascript, se lanza de forma secuencial la carga de los ficheros CSS.

<link /> <link />

<link rel='stylesheet' type='text/css' href='a.css'>
<link rel='stylesheet' type='text/css' href='b.css'>

Sin duda la mejor opción, para todos los navegadores es el uso del tag <link /> que permite que ambos ficheros sean cargados de forma simultánea.

Conclusión

No uses @import. Y si lo has de usar, se consciente de lo que implica.

Carga asíncrona de grandes cantidades de dátos con Ajax

22 mar

+ 31

Ajax es una técnica para cargar asíncronamiente datos que podremos usar en nuestras páginas web. Esta técnica ha permitido a las aplicaciones web que evolucionen hasta el nivel actual y darán lugar a nuevas aplicaciones más potentes y complejas.

Esta técnica se basa en el uso de xmlhttprequest() para lanzar llamadas de forma asíncrona al servidor, pudiendo así devolver datos cargados posteriormente a la carga de la página. De esta forma la carga inicial de la página puede ser menor y dejar a elección del usuario cargar los datos a medida que los vayan necesitando.

El problema no lo encontramos con la cantidad de datos. Si el número de datos devueltos por el servidor es muy alto esto suele convertirse en una larga espera, con el fichero .gif de loading reglamentario.

Para intentar mitigar este problema he estado haciendo una serie de pruebas, con fín de dejar los ficheros XML que hasta ahora he estado usando en algunos proyectos.

XML

Durante mucho tiempo ha sido el sistema usado en muchas implementaciones para obtener datos de forma asíncrona. De ahí el propio nombre de AjaX (Asynchronous JavaScript And XML). Estos ficheros, generalmente ofrecen mayor interconexión con multiples herramientas.

En un uso para carga asíncrona, nos encontramos como príncipal problema el peso del fichero y tiempo invertido en recorrer el fichero XML para obtener los datos.

....
<hotel>
	<code>0000</code>
	<name>Hotel0</name>
	<direction>Calle0</direction>
	<telef>Telf0</telef>
	<geo>
		<lat>00</lat>
		<lng>00</lng>
	</geo>
</hotel>
....
// Javascript
var hotelDescription = data, hotelList = [];
var data = data.getElementsByTagName("hotel");
for (var x in data) {
	var hotel = data[x];
	if (!hotel.getElementsByTagName) continue;
	hotelList.push(hotel.getElementsByTagName("name")[0].firstChild.data);

		hotelDescription[hotel.getElementsByTagName("name")[0].firstChild.data] = {
			code: hotel.getElementsByTagName("code")[0].firstChild.data,
			name: hotel.getElementsByTagName("name")[0].firstChild.data,
			direction: hotel.getElementsByTagName("direction")[0].firstChild.data,
			telf: hotel.getElementsByTagName("telef")[0].firstChild.data,
			geo: {
				lat: hotel.getElementsByTagName("lat")[0].firstChild.data,
				lng: hotel.getElementsByTagName("lng")[0].firstChild.data
			}
		};

}

JSON

La primera alternativa, fué JSON, una implementación muy clara y natural de mostrar datos. Al tratarse de un fichero TXT podemos hacer que ocupe menos espacio y al evitar la estructura XML conseguimos que el tiempo invertido en recorrer el XML para obtener los datos.

Pero por contra, para poder usar los datos obtenidos hemos de usar la función eval() lo que nos penaliza la carga del fichero. Una vez evaluado el código el tiempo empleado en preparar los datos para poder usarlos es mínimo y sin duda, el más rápido de los sistemas exáminados.

....
{
	code: 0000,
	name: 'Hotel0',
	direction: 'Calle0',
	telef: 'Telf0',
	geo: {
		lat: 00,
		lng: 00
	}
}
....
// Javascript
var hotelDescription = data, hotelList = [];
for (var x in data) hotelList.push(data[x].name);

TXT

La gente de Flickr comentaba hace poco como hicieron para devolver más de 10.000 resultados en menos de 200ms. Y obviamente me ví obligado a contemplar esta técnica.

Se basa en usar una estructura preestablecida en un fichero de texto plano. Usando un separador por registro y otro por campos dentro de cada registro. De esta forma a la hora de cargar el fichero simplemente tendremos que hacer una serie de split() para cortar la cadena y convertirla en una variable que podamos usar.

Como mayor ventaja, esta técnica ofrece un tamaño de fichero mucho más pequeño que los comentados anteriormente. Por contra el tiempo de proceso sobre los datos para obtener una variable que pdamos usar es mucho mayor que la necesaria para procesar el fichero JSON, pero bastante menor que el empleado para un fichero XML.

0000:Hotel0:Calle0:Telf0:00:00|...
// Javascript
var tmp = data.split("|");
var hotelList = [];
var hotelDescription = [];
for (var x = 0, len = tmp.length; x<len; x++) {
	var hotel = tmp[x].split(":");

	hotelList.push(hotel[1]);

	hotelDescription[hotel[1]] = {
		code: hotel[0],
		name: hotel[1],
		direction: hotel[2],
		telf: hotel[3],
		geo: {
			lat: hotel[4],
			lng: hotel[5]
		}
	};
}

Comparativas

Para las pruebas, he realizado una pequeña aplicacion que nos permite cargar 500, 1000, 2000, 5000 o 10000 registros en los formatos anteriores (XML, JSON o TXT). Para los gráficos he usado los resultados obtenidos en Firefox 3.0.7 en Mac Os X.

Si queréis podéis probar por vosotros mismos los resultados que obtendríais en diferentes navegadores directamente aqui.

500 registros

500_registros

1000 registros

10000_registros

2000 registros

2000_registros2

5000 registros

5000_registros

10000 registros

10000_registros

Parece que los gráficos hablan por si solos, y podemos sacar una información interesante.

Conclusiones

bigajax

De los resultados obtenemos las siguientes premisas:

XML

  • Son los ficheros más pesados
  • El tiempo de procesamiento es mayor que los demás.

JSON

  • Son los ficheros que más tiempo tardan en cargar completamente.
  • El tiempo de procesamiento es el más rápido de los testeados.

TXT

  • Son los ficheros menos pesados.
  • El tiempo de proceso y carga son bajos aunque no destacan frente a los demás.
  • El tiempo total es el menor de los testeados.

Descargar el proyecto

He subido el proyecto a Github para que los descargueis y usais si quereis.