Publicado el Lunes 20 de Agosto del 2007 @ 20:34 por Armonth.
Una de las formas más radicales de ahorrar ancho de banda en un sitio y acortar los tiempos de carga es comprimir las páginas antes de enviarlas. Vamos a profundizar un poco en el asunto.
Para descomprimir páginas web el navegador no necesita ningún “plugin”. El navegador, si es capaz, abre de forma transparente la página comprimida y la muestra como si fuera HTML “del de toda la vida”.
Tampoco existen incompatibilidades con los distintos navegadores. El navegador decide si puede tratar una página comprimida o no. Si el navegador puede (y hoy en día todos lo hacen) a la hora de enviar la petición para descargar la página lo hace junto a una cabecera “Accept-Encoding” y es ahí donde el servidor decide cómo enviarla.
Podemos usar varios valores para comprimir, pero toca mencionar la parte negativa de usar compresión: aumenta el consumo de CPU.
La buena noticia es que en general sale a cuenta, aunque sólo sea por quitarte más rápidamente las conexiones abiertas (KeepAlive) que también influyen en el consumo de CPU. En general el aumento de consumo no es acusado y compensa. En algunos casos incluso llega a reducirse.
Enviando una petición con “Accept-Encoding: gzip, deflate”. Para ello hay varias formas, una fácil es usar Leknor.com que nos lo dice.
Esta herramienta en el caso de que no enviemos contenido comprimido nos da una tabla, por ejemplo Barrapunto no envía contenido comprimido y vemos que de hacerlo el tiempo de descarga pasa de 18 segundos a 3.5KB/seg (supongamos velocidad de RTB) descargando 67KB a 4.9 segundos con 17KB a descargar. Eso aplicando el nivel de compresión 1 de GZIP.
La otra manera de comprobarlo es mediante el nunca suficientemente apreciado “wget”:
wget -S sigt.net/
19:57:46 (35.05 KB/s) - `index.html' saved [38603]
wget -S --header="Accept-Encoding: gzip" sigt.net/
19:57:55 (19.88 KB/s) - `index.html' saved [10447/10447]
En el ejemplo, vemos que SigT envía las páginas tanto de forma normal como comprimidas, según la necesidad de cada navegador.
A todo lo dicho anteriormente añadir que podemos cambiar “Accept-Encoding: gzip” por “Accept-Encoding: deflate” para usar deflate o “Accept-Encoding: gzip,deflate” para que el servidor pueda elegir entre los dos.
Existen muchas maneras de implementar compresión en páginas, la primera pregunta que hay que hacerse es ¿gzip o deflate?. Ambas ofrecen lo mismo pero deflate es más rápido en Apache2.
Vamos a tratar ambas opciones a nivel de módulo para Apache, aunque nada nos impide copiar un HTML estático, comprimirlo con gzip, hacer un script en PHP que haga la negociación de contenidos y encima ahorrarnos la compresión “al vuelo” aunque para sitios grandes puede ser algo complejo de implementar.
La forma de instalar mod_gzip es simple y en Debian con un apt-get install libapache-mod-gzip ya lo tendremos hecho, sólo faltará buscar en el fichero /etc/apache/httpd.conf la línea:
#LoadModule gzip_module
Y descomentarla. Luego deberiamos ver algo parecido a:
<IfModule mod_gzip.c>
Include /etc/apache/mod_gzip.conf
</IfModule>
Que nos esta indicando donde se guarda la configuración de mod_gzip, existen muchos valores y en general los usados por defecto son buenos pero cabe mencionar los siguientes:
mod_gzip_on Yes
mod_gzip_can_negotiate Yes
mod_gzip_minimum_file_size 400
mod_gzip_item_include file .html$
mod_gzip_item_exclude file .css$
El primer valor es obviamente para activar mod_gzip, el segundo es muy importante ya que se asegura de que se pueda mantener la “negociación” que hemos visto antes (que el navegador pueda recibir el contenido comprimido o no). La tercera línea sirve para que no se comprima nada inferior a 400 bytes dado que no sale a cuenta.
Las dos últimas líneas (que se pueden repetir lo que haga falta) son para incluir o excluir respectivamente los ficheros terminados con esa extensión, por ejemplo no es buena idea comprimir CSS porque aparte de que suele ocupar muy poco, Internet Explorer 6 no lo acepta comprimido.
Deflate viene a ser en Apache 2.x el sustituto de gzip que ha sido usado intensamente en Apache 1.3.x y en general suele ser más rápido.
Para activar mod_deflate los pasos son prácticamente los mismos, pero en Howto Forge hay un completo manual para implementarlo.
Sólo se me ocurre un problema: su incompatibilidad con wp-cache en WordPress, como bien sabes.
PD: acabo de actualizar mis filtros antipublicidad para AdBlock. He incluido a los periódicos de hispanoamérica. Los siguientes son una selección del resto del mundo.
Tate, tienes razón. He de actualizar varias bitácoras a WP 2.0.11 final (evito a toda costa la rama 2,1 y la siguiente 2,2) así que probaré a implementar esa funcionalidad si está permitido en las cuentas en servidores web compartidos.
Exacto, ahí está el problemilla, se requiere tener acceso al servidor. Hummm… ya contaré (siempre puedo pedir que implementen tal funcionalidad si no lo está como me parece -me suelen hacer caso).
Ya contaré.
¿Y para hacerlo en Dreamhost? Porque creo que sigt está allí, y también creo que no hay acceso al httpd.conf… ¿o sí?
Yo creo que tengo metido el deflate y me ahorro muchos kas de ancho.
Por cierto, yo para comprimir uso lo siguiente:
#Comprimimos
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
<Location />
# Insert filter
SetOutputFilter DEFLATE
# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images (Ni los torrents ni nada que me acuerde que no hay que comprimir!!)
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|ico|torrent|rar|zip|exe|avi|mkv)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>
Vaya, acabo de comprobarlo y por lo que parece ya envía comprimido… y yo sin saberlo :)
He estado mirando en cPanel de una cuenta bastante completa y no veo cómo implementarlo, como temía.
Tampoco mi bitácora en Nireblog está comprimida. Ahí sí que David tiene acceso al servidor, por lo que le daré un toque.
Enhorabuena Armonth por el artículo.
Creo que puede ser muy útil si decidimos tener en cuenta el punto número 4 de las Rules for High Performance Web Sites que nos recomiendan desde Yahoo! y que podemos comprobar con YSlow
Un saludo!
¡Ojo! Creo que en Dreamhost tienen el módulo cargado, pero no está activado por defecto para ciertos ficheros. Tuve una conversación con un chico del soporte técnico acerca de ello.
En mi caso (Uso PHP5, Apache2 con deflate) solo tuve que añadir la siguiente línea en el .htaccess del sitio:
AddOutputFilterByType DEFLATE (MIME)
Donde (MIME) son los MIME de los ficheros que quieres comprimir:
text/javascript para ficheros .js
text/css para ficheros .css
text/html para ficheros .html
application/xml o text/xml para ficheros .xml
etc…
Igual me equivoco, pero creo que -al menos en mi servidor de Dreamhost- es así.
Saludos :)
“…estaba intentando aplicar el Gzip que maty pidió para su blog, por favor infórmele que no es posible por consumo de CPU”
La respuesta es lógica, puesto que el modelo de negocio en ese hosting se basa en el consumo de ancho de banda, a diferencia de Dreamhost. Dicho consumo está supercontenido, por la gran optimización del tema utilizado en WP y porque las imágenes de las anotaciones se alojan en una cuenta externa en Flickr (práctica en extremo aconsejable).
Pregunta
¿Se puede habilitar la compresión sólo para una cuenta y no para todo el servidor web compartido?
Hola, he tratado de utilizar el metodo de com`presion mod_gzip para mi sitio pero no consigo que php config muestre otra cosa mas que auto_append_file no value no value, y esto localmente, ahora mucho menos modificar el servidor.
Por favor diganme como lo hago, ya sea modificando el .htaccess o como sea posible. Gracias.