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!
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