tip 12 – Como paralelizar el trabajo del cliente y el servidor con “Flush”

Si bien en este blog se trabajo sobre la idea de que la mayor parte de las mejoras que se pueden realizar para optimizar la performance de un web site, no están en el código del servidor. Existen algunos casos que un pequeño truco puede ayudarnos mucho en una página que tiene una demora muy alta en construirse en el servidor. Por ejemplo cuando debe realizarse una consulta muy lenta a una base de datos o bien cuando consultamos un servicio web externo, etc.

En la mayoría de los lenguajes server-side como: PHP, Python, ASP, JSP, Perl, etc ; existe una función para poder hacer un flush del contenido antes de finalizar la ejecución de una página. Que significa esto: que nosotros podemos disponer que en determinado instante, el servidor comience a transmitir el Response del HTTP Request recibido. Esto permite que el browser (el navegador del cliente), empiece a procesar e interpretar el contenido recibido, aún si el servidor sigue procesando el request original.

Por ejemplo,  si tenemos una página web que en la mitad de la misma, el en servidor consulta un servicio web externo para formar un listado, y esto demora mucho. Podemos poner antes de ejecutar esa llamada externa un “flush()” y de ese modo permitir que el servidor web paralelamente envie el contenido generado hasta el momento al cliente. Esto tipicamente es el “header” y parte del “body” donde ya puede contener enlaces a componentes externos como CSS, Imagenes, etc. De ese modo, el browser puede iniciar la descarga de estos componentes, mientras el servidor web continua procesando página. Y asi trabajar en paralelo para reducir al máximo la demora y mejorar notablemente la performance.

El secreto es saber ubicar en el lugar adecuado el Flush, el caso típico es después del header, en otros casos lo he utilizado en algún ciclo donde tenia muchas consultas a servicios web externos,  para ir dando los resultados parcialmente.

Lamentablemete esto no se puede realizar en algunos sistemas de templating como el de Django.

Les dejo un enlace a la docu de Flush en PHP

Suerte :)

Posted in performance, webapps | Tagged , , , , , , | 2 Comments

Videos de Steave Souder en la universidad de Stanford

Les quería dejar el enlace a las tres primeras clases de ” High Performance Web Sites ” en facultad de Computer Science la universidad de Stanford dictadas por el investigador y ahora colaborador de Google Steave Souder.

Los videos aquí

Lamentablemente solo podemos ver las 3 primeras y si queremos ver el resto debemos pagar u$ 600. Otra cosa, para verlos deben tener “Microsoft Silverlight” :(

Espero los disfruten como yo.

Suerte :)

Posted in performance | Tagged , , , , , | Leave a comment

tip 11 – Descargas en paralelo

tip: utilizar entre 2 y 6 hostnames para componentes estaticos (CSS, JS e Img)

Por una especificación de HTTP 1.1 muchos navegadores tienen el limite de descarga de hasta dos componentes en paralelo por hostname. Obviamente esto perjudica la performance de carga de nuestra web. Aunque por suerte en las últimas versiones de Firefox, IE, etc este límite se ha modificado a 6.

Como sabemos, un website o webapp tiene muchos componentes externos al HTML principal, y los mismos deben ser descargados por el navegador ( a menos que esten en cache ). Este costo de descarga es muy facil de reducir si podemos paralelizar la descarga de los mismos.

Ejemplo de como ganar performance maximizando la descargas en paralelo:

Si tenemos un html donde hay 10 imagenes como las siguientes:

<img src=”misitio.com/imagen1.jpg” />
<img src=”misitio.com/imagen2.jpg” />
<img src=”misitio.com/imagen3.jpg” />
<img src=”misitio.com/imagen4.jpg” />
<img src=”misitio.com/imagen5.jpg” />
<img src=”misitio.com/imagen6.jpg” />
<img src=”misitio.com/imagen7.jpg” />
<img src=”misitio.com/imagen8.jpg” />
<img src=”misitio.com/imagen9.jpg” />
<img src=”misitio.com/imagen10.jpg” />


(supongamos que todas tienen el mismo peso 10k, y demoran 1 segundo en descargar para simplificar el ejemplo)

En un navegador estandar demoraría en descargar esas imagenes 5 segundos, ya que solo puede descargar dos a la vez. Pero si cambiamos el numero de hostnames a 2 de esta forma:

<img src=”img1.misitio.com/imagen1.jpg” />
<img src=”img1.misitio.com/imagen2.jpg” />
<img src=”img1.misitio.com/imagen3.jpg” />
<img src=”img1.misitio.com/imagen4.jpg” />
<img src=”img1.misitio.com/imagen5.jpg” />
<img src=”img2.misitio.com/imagen6.jpg” />
<img src=”img2.misitio.com/imagen7.jpg” />
<img src=”img2.misitio.com/imagen8.jpg” />
<img src=”img2.misitio.com/imagen9.jpg” />
<img src=”img2.misitio.com/imagen10.jpg” />


Podríamos bajar el tiempo a 3 segundos. Y si utilizamos un 3 hostname img3.misitio.com, podríamos bajar el tiempo a 2 segundos. Y “en teoría” con 5 hostnames el tiempo de descarga de todas las imagenes sería de 1 segundo.

En realidad cuantos mas hostnames agregamos mas paralelizamos la descarga, pero también esto trae otros costos, como mayor consumo de CPU en el navegador del cliente, mayor consumo del ancho de banda, y sobre todo mayor tiempo en la resolución de los DNS de cada hostname.

Por ende y como explican en este artículo lo mejor es manejar entre 2 y 6 hostnames.

Suerte ;)

Posted in performance | Tagged , , , , , | 4 Comments

tip 10 – Evitar el boqueo de la página por Adsense (u otro javascript)

Bueno, esta es una técnica para poder cargar y ejecutar scripts externos sin que estos bloqueen la renderización de la página y la descarga de otros componentes en el navegador. Como ya lo he explicado en los anteriores posts.

El caso mas común donde esto afecta realmente nuestro site es con los ads, donde nosotros no tenemos ningún control en el tiempo de descarga y ejecución. Y en el caso mas común como Adsense, donde el script es colocado en varios lugares de la página y sobre todo en el header de la misma,  es frecuente ver como cualquier página con mucha publicidad tarda mucho en mostrarse.

Veamos el problema:

Google inteligentemente, nos da un script para pegar en una página que contiene 2 scripts:

<script type=”text/javascript”><!–
google_ad_client = “pub-32416930xxxxxxx”;
//468×60, creado 25/01/08
google_ad_slot = “522822xxxx”;
google_ad_width = 468;
google_ad_height = 60;
//–></script>
<script type=”text/javascript”
src=”http://pagead2.googlesyndication.com/pagead/show_ads.js”></script>

El primero tiene las variables necesarias para indicar que publicidad y que cuenta es, y el segundo que se carga externamente crea un iframe donde carga otros scripts y finalmente el html que se ira a mostrar.

Esto afecta la performance de carga hasta que es creado el iframe, donde el browser puede seguir en paralelo, la carga de otros componentes o la renderización del resto de los componentes.

Pero tiene un gran impacto. Y lamentablemente este script no puede ser movido al final de la página como dice una de las principales reglas de performance.

Ahora si el Tip:

Esto es muy simple de solucionar si modificamos levemente el script de adsense (o cualquier otro)  agregando un ID y la orden de eval cuando lo cargue, y borrando el atributo de SRC.  Quedaría:

<script type=”text/javascript”><!–
google_ad_client = “pub-32416930xxxxxxx”;
//468×60, creado 25/01/08
google_ad_slot = “522822xxxx”;
google_ad_width = 468;
google_ad_height = 60;
//–></script>
<script type=”text/javascript” id=”ads_script” onload=”eval(text)”></script>

Finalmente solo debemos poner en el final de la página este pequeño script:

url = ‘http://pagead2.googlesyndication.com/pagead/show_ads.js’;
document.getElementById(’ads_script’).src = url;

Eso es todo!!

De esta sencilla forma, logramos que el sitio se muestre primero y luego cargue las publicidades, algo realmente muy importante en muchos casos, sobre todo en los blogs.

Espero que este tip de performance les permita optimizar sus sitios.

Suerte ;)

Posted in performance | Tagged , , , , | 7 Comments

tip 9 – Evitar el bloqueo al cargar javascripts

Como lo he comentado anteriormente cada browser tiene un comportamiento bastante malo en la performance de nuestro site en el momento de cargar e interpretar un script, ya sea externo o un tag de la misma página. Tanto IE, FFX, Chrome y Safari tienen bloqueos cuando cargan el script.

Los bloqueos los podemos separar en dos tipos:

  • No descarga otros elementos de la página.
  • No dibuja(renderiza ) los elementos inferiores durante la carga y ejecución del script.

Estos bloqueos básicamente son por la política “un script puede modificar la página, entonces no hago nada hasta que se cargue y ejecute.” Esto es básicamente lo que piensa un navegador, y es por eso que nos trae tan malas consecuencias de performance.

Aca podemos ver un ejemplo de como quedan los elementos esperando la descarga de los dos primeros scripts:

Steave Souder, escribió un artículo explicando las distintas técnicas para poder cargar scripts sin que estos bloquen el browser. La aplicación de cada una de estas técnicas depende del entorno de nuestro sitio o webapp. Por ende no existe una mejor que la otra, pero podemos decir que la que mejor se comporta en todos los navegadores es “Script DOM Element”.

Las distintas técnicas serían:

  • XHR Eval – Descargar el script via XHR y  cargarlo al DOM con eval() de la respuesta del XHR.
  • XHR Injection – Descargar el script via XHR , crear un script tag e inyectarle el texto de respuesta del request.
  • Script in Iframe – Este es un Wrapper, donde incluimos un iframe con un html que solo contenga los scripts que queremos cargar. Esta es la técnica mas usada por adsense y otros ads.
  • Script DOM Element – crear un tag en el DOM y setearle la url al script en el src.
  • Script Defer – Agregar el atributo defer al tag script, lamentablemente solo funciona en IE y FFX>3.1
  • document.write Script Tag – Escribir <script src=""> HTML en la página usando  document.write. También solo funciona en IE

En el próximo artículo vamos a publicar un ejemplo de cada técnica.

Suerte ;)

Posted in performance, webapps | Tagged , , , | Leave a comment

news – High Performance Web Site (reloading…)

Hace solo unos días que se publico el nuevo libro de Steave Souder “Even Faster Web Sites“, editado por O’Reilly puede ser adquirido en Amazon.com .

Este es el segundo libro de este gran investigador del equipo de Best web Perfomance de Yahoo, quienes son los responsables de grandes herramientas como YSLOW y técnicas de performances para webapps como las “Speed up rules” .

El anterior libro Steave desarrollo la explicación de su investigación en Yahoo y las mejores prácticas afin de mejorar la performance de un web site.

En este nuevo titulo, el autor profundizo en las investigaciones , ampliando el campo de prueba a todos los navegadores y versiones posibles. Y incluyo técnicas avanzadas para la mejora de la performances. Los temas nuevos son:

  1. Understanding Ajax Performance – Doug Crockford
  2. Creating Responsive Web Applications – Ben Galbraith and Dion Almaer
  3. Splitting the Initial Payload
  4. Loading Scripts Without Blocking
  5. Coupling Asynchronous Scripts
  6. Positioning Inline Scripts
  7. Writing Efficient JavaScript – Nicholas C. Zakas
  8. Scaling with Comet – Dylan Schiemann
  9. Going Beyond Gzipping – Tony Gentilcore
  10. Optimizing Images – Stoyan Stefanov and Nicole Sullivan
  11. Sharding Dominant Domains
  12. Flushing the Document Early
  13. Using Iframes Sparingly
  14. Simplifying CSS Selectors
  15. Performance Tools

Suerte ;)

Posted in performance | Tagged , , , | Leave a comment

Tip 8 – El mejor amigo del optimizador web : YSLOW

Para los ansiosos, el tip: entra y descarga el YSLOW aca

Ahora si la explicación:

Desde que me dedico a optimizar webapps y websites la mejor herramienta que he encontrado es el YSlow, cuya traducción es un juego de palabras que significa: “Por que es lento”. ;)

El YSlow es un plugin para el Firebug que es otro excelente plugin para Firefox, seguro que si desarrollas webs lo conoces, y si no es asi acabas de encontrarte con un nuevo mundo. :)

YSlow esta desarrollado por el equipo de Exceptional Performance de yahoo, el cual dirige nuestro amigo Steave Souder. Que por suerte han liberado para nuestro uso.

Como verán al probarlo, es extremadamente simple y potente. Basicamente nos permite calificar de un click cualquier web, para identificar cuales son las cosas básicas que se pueden modificar para mejorar la performance, según las reglas de performance que aconsejan en Exceptional Performance.

También podemos ver las estadísticas de uso de cache en una webapp.

YSlow stats

YSlow stats

Y finalmente analizar en detalle cada uno de los componentes del frontend de una web, como por ejemplo el header HTTP de cada componente

Verán que esta herramienta los ayudará mucho a eliminar problemas básicos o medios para mejorar la performance de nuestro website o webapp.

Suerte

Posted in performance, webapps | Tagged , , , , , , | Leave a comment

Tip 7 – Como optimizar una web – Donde empezar

En este post voy a brevemente tratar de comentarles como llevar adelante una optimización de un website o webapp.

En principio, debemos entender como trabaja un browser, la red y el web server.  Luego, ponernos en contexto de cual es el tipo de web que vamos a analizar: si es de contenido, publica o privada, etc.

Quizás lo mas importante para nosotros es saber que la performance de un web site esta definido por el tiempo que transcurre desde que un navegador solicita una página y la misma se termina de renderizar o dibujar y esta disponible para el usuario. 

En ese proceso podemos ver cuatro grandes factores para identificar problemas:

  1. Request usuario al server:   Aquí mayormente tenemos problemas clásicos como DNS lookups, lentitud del cliente, CDN, etc
  2. Revolución del servidor web: el tiempo en que el servidor responde al recurso que solicitamos, ya sea estático o dinámico. Aca vamos a ver un gran grupo de problemas como cache, dbms, optimización de código, etc.
  3. Transmisión desde el servidor web al navegador:  Aquí hay problemas que tienen que ver con la cantidad de componentes, la compresión de los mismos CDN, cantidad de hostnames, etc.
  4. Renderizado o dibujado: donde tenemos temas como la posición de los componentes CSS y Javascript, imagenes, elementos del DOM y otras cosas.

Muchas veces es muy útil analizar los problemas por separado, aunque hay soluciones que atáñen a mas de un paso del proceso. 

Espero que este pequeño tip, les ayude a identificar mas claramente donde tienen sus problemas. Pero no olviden que los problemas mas simples de solucionar están en los pasos 3 y 4, y generalmente son los que mayor impacto tienen en la mejora de la performance de nuestra webapp.

Suerte

Posted in performance | Tagged , , , | Leave a comment

Tip 6 – Minimizar la cantidad de elementos del DOM

El tip:  Minimizar la cantidad tags (elementos del DOM) 

La explicación:

 Es común trabajar con diseñadores que definen el layout de nuestra webapp o website con una herramienta WYSIWYG, como por ejemplo Dreamweaver.  Los diseñadores definen ahí el contenido y disposición de los elementos en la página, sin ver que el HTML que genera esa herramienta, es en la mayoría de los casos totalmente ineficiente. 

Por ejemplo, la mayoría de los diseñadores utilizan Tablas, para el layout y esto, como ustedes saben, genera un “horrible” código HTML muy complicado de mantener y sobre todo muy ineficiente. Ya que normal ver tabla sobre tabla sobre tabla, sobre tabla…  Cuando en realidad es muy simple manejar el layout con DIVs y CSS. 

Si tenemos una página sobrecargada de elementos, generamos dos problemas: 

  1. Tenemos que transferir mayor cantidad de bytes por la red.
  2. Tenemos un DOM mas complejo para el layout engine del navegador, por ende el renderizado y las acciones de Javascript van a ser mucho mas lentas. 

Es relativamente sencillo entender bien el uso del CSS para la distribución de los elementos, y un DOM puede bajar de 4500 a 300 como nos ha pasado en algunas optimizaciones. Obviamente, el navegador responde varias veces mas rá¡pido a una pagina de esas características ganando mucha performance en loading y rendering. 

Es muy simple saber la cantidad de elementos que tenemos en la página con solo poner en la consola del Firebug:

document.getElementsByTagName(’*').length

En resumen: 

  No definas nunca un layout con tablas. 

Suerte

Posted in performance, webapps | Tagged , , , , , | Leave a comment

Tip 5 – Ganar performance utilizando el cache mediante el htaccess

para los ansiosos el tip (es un ejemplo que depende de cada casa optimizarlo a sus necesidades):

# Turn on Expires and set default to 0
ExpiresActive On
ExpiresDefault A0

# Set up caching on media files for 1 year (forever?)
<FilesMatch ".(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
ExpiresDefault A29030400
Header append Cache-Control "public"
</FilesMatch>

# Set up caching on media files for 1 week
<FilesMatch ".(gif|jpg|jpeg|png|swf)$">
ExpiresDefault A604800
Header append Cache-Control "public"
</FilesMatch>

# Set up 2 Hour caching on commonly updated files
<FilesMatch ".(xml|txt|html|js|css)$">
ExpiresDefault A7200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>

# Force no caching for dynamic files
<FilesMatch ".(php|cgi|pl|htm)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"

</FilesMatch>

La explicación completa:

Con el pasar de los años las paginas van ganando peso (mas js, mas css, mas imagenes y mas flash). Por suerte, los navegadores y proxys usan mecanismos que cache, que supongo sabes lo que significa. Ahora bien, los mecanismos de cache tienen su complejidad, ya que de alguna manera el servidor web debe indicarle al browser cuando guardar y cuando solicitar nuevamente el contenido de un componente de la pagina (archivo css, js, img, etc). Esa comunicación se realiza por medio de headers en el mensaje HTTP entre el navegador y el servidor web.

Gracias a esos mecanismos de chache podemos ganar muchísima performance en la carga cada página de nuestro website o webapp. Ya que si pensamos que en un caso típico, solo el 5% del peso de una página es contenido dinámico(HTML generado), el resto puede ser guardado en el navegador y la segunda vez que el usuario ingrese a esa página o bien necesite alguno de esos componentes, el navegador los tendrá en disco para leerlos directamente. Por ende podemos intuir una ganancia del 95% en la transmisión de la página.

El secreto de una buena utilización de la cache es saber determinar, cuanto tiempo le permitimos guardar al navegador cada archivo. Y en general la respuesta es para cada caso. Pero si pensamos en casos típicos lo que nos recomiendan nuestros amigos de yahoo high performance es manejar dos tipos de cache:

Para contenido dinámico (que puede cambiar) usamos el header cache-control para decirle al navegador que ese contenido necesita revalidar la antigüedad. Esto generalmente utiliza un request en la carga, pero la respuesta es un mensaje HTTP 304, con lo que no se vuelve a transmitir el contenido del archivo, por lo que es altamente mucho mas performante.
Para el contenido estatico (contenido que no cambia “casi” nunca como Imagenes, CSS, JS, Flash, etc), usamos la política “Never Expire”, con lo cual indicamos que ese archivo nunca cambiara, y por ende puede el navegador tomarlo siempre de su cache. Evidentemente, siempre debemos realizar un cambio hasta en las imagenes, por lo que conviene realizar un cambio en el nombre del componente. Habitualmente se utiliza nombre_fecha o nombre_version. De esa forma, cambiamos el recurso y obligamos al navegador a pedir la nueva versión.

Bien, ahora que sabemos porque y que hacer, les voy a comenta un poco del como hacerlo. En principio existen dos métodos para definir que tipo de cache definimos a cada archivo.  En el método dinámico, seteamos el header en el lenguaje de programación que estemos utilizando en el servidor web, eso es fácil de hacer en Python, PHP, ASP, JSP, etc y no voy a dar ejemplos ya que esta lleno. La otra manera es el método “estático” que consiste en definir los header en el .htaccess de nuestro web site. Existen muchas formas de hacerlo, y debemos tener en cuenta la problematica y la distribución de nuestros archivos. Pero la mas fácil y general de hacerlo es como comente en el principio del post.

También, podemos poner varios .htaccess en el site, como ya saben, uno en cada carpeta redefiniendo para ese contenido la política.

Aclaración para HTTPS:

Por una pólitica de seguridad los navegadores no guardaban en cache ningún contenido cuando se trabaja sobre HTTPS o SSL sobre HTTP. Pero desde la versión FireFox3 y una actualización de IE7 permiten que se guarde en cache aquel archivo que contenga la directiva en el header “Cache-control public”. De esta forma lo autorizamos al navegador desde el servidor web a poder hacer uso de la pólitica cache que el crea conveniente para ese componente.

En Resumen, en la actualidad es muy importante para todos los sitios de gran contenido estático como imagenes y demas, hacer un buen uso de la cache de los navegadores. No solo por la performance de los website, sino también por la usabilidad que perderán los usuarios del mismo si no lo tienen habilitado.

Para los mas lectores:

Un post con mucha información sobre el tema

Suerte!

Posted in performance, webapps | Tagged , , , , , , , | 1 Comment