martes, 8 de enero de 2008

Mejora tu sitio utilizando sólo HTML (parte 2)


Continuando el post de ayer, enterate que otros pequeños cambios puedes realizar en el HTML para mejorar tu sitio, esta vez, en lo que refiere a la velocidad de carga.


Continuando lo posteado ayer, quisiera hoy hablar sobre los pequeños y sutiles cambios que uno puede hacer al HTML para lograr grandes mejoras, en esta ocasión, en lo que refiere a la velocidad de carga del sitio.

Hace ya varios años, cuando internet en Argentina era cosa de pocos, con conexiones dial-up a través de la UBA, y un poco más tarde aún, cuando altavista era el mejor navegador que conociamos, leí un artículo que decía que el tiempo de tolerancia de carga de un sitio era de 10 segundos aproximadamente. En su momento, 10 segundos de hecho, podía parecer incluso poco a quienes navegabamos, pero estabamos acostumbrados a esperar. Internet recién estaba ganando popularidad por lo que la cantidad de contenidos no eran tantos, y cada sitio era único y valía esperarlo.

Hoy en día no sólo las conexiones se han hecho cientos de veces más rápidas, sino que la cantidad de material en internet ha crecido extraordinariamente, y los buscadores han mejorado a la par. Ante cualquier busqueda recibimos miles de sitios con la respuesta. Ahora, incluso si mi sitio rankea primero, ¿por qué va a tener uno que esperar 2 segundos más en abrirlo si el sitio de abajo tiene la misma información?

Con el aumento de la velocidad de conexión y la proliferación de sitios web, la tolerancia de carga se ha visto muy disminuida, y los sitios por su parte se han vuelto más pesados que nunca (Flash, Java, CSS, JS, imágenes). Es por tanto muy importante mantener nuestro sitio ágil en la navegación. un sitio rápido que no me saca tiempo lo puedo mirar en cualquier momento, si sé que cada página tarda 10 segundos en cargar, voy a dejar de entrar desde la oficina por si cae mi jefe, voy a dejar de leerla en casa porque me aburre, voy a dejar de entrar.

Muchas veces, al analizar como acelerar nuestros sitios la única solución que se nos ocurre es eliminar imágenes, dividir el texto en varias páginas, bajar la calidad de imágenes, etc. Y aunque son técnicas efectivas, deberían de ser nuestro últimor ecurso, y no el primero, pues impactan directamente sobre el como el usuario percibe al sitio. Hacer al sitio menos atractivo puede implicar eliminar aquello que hizo venir al usuario en primer lugar. Nuevamente, sitios como Dosual no se pueden dar el lujo de no mostrar imágenes.

Es por tanto necesario hacer otras cosas, y el primer paso para poder mejorar es entender como se carga nuestro sitio, o lo que es lo mismo, como trabaja un navegador. A saber, no pretendo un conocimiento exhaustivo sobre lo que hace internamente, de hecho, sólo hace falta un conocimiento bastante superficial para lo que pretendo.

Asumo todos abrán visto alguna vez un sitio con muchas imágenes grandes, donde 2 o 3 imágenes se van dibujando al mismo tiempo, de arriba hacia abajo con el texto ya visible. Esto ya nos da una primera pista de como funciona un navegador: paraleliza las descargas. Cuando un elemento que se puede paralelizar se encuentra, el browser continua procesando el HTML, e intenta dibujarlo dejando la carga del mismo en segundo plano. Esto permite empezar a dibujr cosas antes y dar una impresión de mayor velocidad. Uno puede navegar el sitio desde antes. Sin embargo, existe una creencia de que todo elemento externo es paralelizado, y temo esto es falso.

Si bien los CSS se pueden cargar en paralelo, así como imágenes o componentes Flash, los archivos JS no tienen la misma suerte. Para muchos esto podrá sonar extraño, pero tiene una excelente explicación. Es posible desde JS, haciendo uso de document.write agregar texto al HTML mientras carga. Como el donde se ubica dicho texto es importante, el explorador no puede asumir nada y al encontrar un tag <script> no puede más que dejar de procesar el HTML e ir a buscar el JS, para cargarlo y ejecutarlo.

Ahora bien, hay algo importante aquí. Posiblemente hayan notado que es práctica común de la gran mayoría de los programadores web incluir los <script>, en especial aquellos que incluyen archivos externos, dentro del <head>. ¡El hacer esto está obligando al explorador a no mostrar nada (salvo quizás el título si estaba antes del <script>) y por tanto, dando una impresión de cargar sumamente lento!

Ahora bien, el tag <script> tiene un atributo defer, que le indica al explorador que comience a bajar dicho archivo, pero continue procesando, pues el mismo no escribe nada en el documento, pero a saber, que no todos los exploradores lo soportan, por lo que su uso es desaconsejado.

Por otro lado, y dado que uno puede incluir tags <script> en cualquier sitio, no hay motivo por el cual uno no pueda poner los mismos tan abajo como quiera. De hecho, esto da lugar a un control mucho más fino de como carga nuestro sitio.

No sólo podemos permitir que se renderice el texto y se comiencen a bajar las imágenes al momento de cargar el js, sino que además obtenemos un control mucho más fino sobre el momento enque el mismo se ejecuta.

Supongan el siguiente caso. Tienen un sitio de comercio electrónico. No desean que Google cachee los precios de los elementos, pues estos pueden variar, entonces deciden que los precios se cargarán con un pedido AJAX al servidor. Este pedido no puede realizarse si el DOM no está listo para realizarse. Supongamos además, que en la aprte inferior de su sitio tienen varias publicidades, en particular de esas con imágenes que tardan en cargar.

En un approach tradicional, cargaríamos el JS en el head, y el pedido AJAX lo haríamos en un evento onload. Esto implica, que no sólo el sitio no mostrará nada hasta que el JS haya cargado, sino que el precio no se pedirá (ni hablemos de mostrarlo) sino hasta que terminen de cargar las publicidades. Es decir, ¡estamos subordinando la velocidad de carga de NUESTRO sitio a la velocidad de un servidor que no conocemos, y con imágenes de las que n otenemos ningún control respecto del peso!

Sin embargo, existen alternativas. Como ya hablamos podemos mover el JS hacia abajo y evitar el primer problema, pero esta misma solución también nos permite evitar el segundo problema. Alcanza con no colocar el JS al final de todo, sino justo por encima de las publicidades y debajo de los elementos que queremos manipular, y en vez de utilizar un evento onload, ejecutar el código allí mismo.

Como los elementos de DOM que queremos modificar ya están cargados, podemos hacer el pedido sin miedo, y dado que el script se ejecuta y carga antes que la publicidad, no dependemos de la misma.

A esta altura, nuestro sitio es completamente funcional mucho antes, ya que el sitio es navegable desde un primer momento e incluso si quedan cargar las publicidades, elcontenido (lo que le importa al usuario) ya está allí.