Cómo optimizar un sitio web con compresión GZIP en Nginx y Apache HTTPD

Escrito por el .
planeta-codigo software software-libre web
Enlace permanente Comentarios

Comprimir el contenido es de utilidad para aquellos usuarios a los que se les factura por los datos transmitidos o tienen límites de transferencia en sus contratos con los proveedores de banda ancha o red móvil. Modificando la configuración del servidor web que usemos haremos que nuestra página o aplicación web comprima el contenido que envía a los navegadores de los usuarios reduciendo los datos transferidos y optimizando el sitio web.

Nginx

Apache HTTPD

Con las velocidades de transferencia que proporciona la fibra, el ADSL incluso el 4G o 3G de los móviles transmitir el contenido de una web desde el servidor al cliente ya no es el factor más determinante en el tiempo de carga de una página, lo es más la latencia de la red y el establecimiento de múltiples conexiones. Aún así hay usuarios que por una red de baja calidad o que esté saturada pueden tener tasas de transferencia bajas o puede que al usuario se le facture por la cantidad de datos que transmite. Por estos motivos aún hoy es buena idea activar en el servidor la compresión GZIP para que los datos transmitidos se compriman y reduzcan de forma significativa. La compresión GZIP es una optimización que podemos realizar para cualquier página web. Para mejorar la latencia en el establecimiento de conexiones es aconsejable configurar HTTP/2 en el servidor web para mejorar la velocidad de carga de la página.

Dependiendo del servidor web la configuración que deberemos añadir será diferente, en este artículo mostraré la configuración a usar para dos de los servidores web más populares en internet, que son Nginx y Apache HTTPD.

Nginx

Usando varias directivas de Nginx para la compresión la activamos, establecemos el nivel de compresión, el tamaño de los buffers dedicados a la compresión y finalmente los mimetypes de los archivos que queremos sean comprimidos antes de enviarse al cliente (el texto plano, contenido CSS, JSON, XML, RSS y JavaScript). El mimetype text/html no hace falta indicarlo porque siempre está activo y para los formatos de archivos que ya están comprimidos es innecesario como fotos o vídeos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
server {
  listen       80;
  server_name  localhost;

  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

  location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
  }
}
nginx.conf

Para probarlo usaré un contenedor de Docker en el que personalizaré la configuración y usaré mi propia bitácora como página web a servir. Para conocer Docker puedes consultar otra serie de artículos sobre Docker dedicados a esta tecnología de contenedores. Escrito el archivo de configuración, el contenedor se inicia con:

1
2
$ docker run --rm --name nginx -p 80:80 -v `pwd`/nginx.conf:/etc/nginx/conf.d/default.conf:ro -v /home/picodotdev/Software/personal/git/blog-bitix/public:/usr/share/nginx/html:ro nginx

docker-nginx.sh

En la siguiente captura se aprecia que Nginx devuelve la cabecera de respuesta Content-Encoding: gzip indicando que el contenido ha sido comprimido antes de su transmisión por la red. Haciendo que Nginx haga de servidor web para mi propia bitácora se pueden apreciar la significativa diferencia en kilobytes transmitidos entre el tamaño que tienen y lo transferido para algunos recursos. Por ejemplo, el HTML de la página de inicio tiene un tamaño sin comprimir de 34,11 KB y comprimido un tamaño mucho menor 8,38 KB, una diferencia de 25,73 KB aproximadamente un ratio de compresión del 75%. Para el recurso bootstrap.min.css que ya está minificado eliminando caracteres innecesarios es aún más significativo de 118,43 KB a 23,36, 95,04 KB menos un 80% de reducción.

Unos pocos kilobytes no son mucho para un único recurso pero si tenemos en cuenta que una página tiene varias docenas y hacemos una multiplicación por cada acceso a una página la cantidad de datos ahorrados en la transferencia es notable.

Nginx configurado sin compresión GZIP Nginx configurado con compresión GZIP

Nginx configurado sin y con compresión GZIP

Apache HTTPD

Activado el módulo para realizar la compresión al igual que el caso de Nginx podemos establecer la cantidad de memoria reservada para la compresión, el nivel de compresión y los mimetypes del contenido a comprimir. Con las directivas adicionales de la documentación se puede personalizar aún más el proceso de compresión.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
LoadModule deflate_module modules/mod_deflate.so
...
<VirtualHost *:80>
   ServerName localhost
   DocumentRoot /usr/local/apache2/htdocs

   SetOutputFilter DEFLATE
   DeflateBufferSize 8096
   DeflateCompressionLevel 6
   AddOutputFilterByType DEFLATE text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript
</VirtualHost>
httpd.conf
1
2
$ docker run --rm --name apache -p 80:80 -v `pwd`/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro -v /home/picodotdev/Software/personal/git/blog-bitix/public:/usr/local/apache2/htdocs:ro httpd

docker-httpd.sh

Vemos una reducción en la transferencia similar a la conseguida en Nginx. En Apache el recurso a servir ha de tener cierto tamaño siendo de unos pocos bytes opta por servirlo sin comprimir ya que considerará que no producirá un ahorro significativo.

Apache HTTPD configurado sin compresión GZIP Apache HTTPD configurado con compresión GZIP

Apache HTTPD configurado sin y con compresión GZIP

La compresión se hace en cada petición que se hace al servidor que con los avanzados procesadores actuales con eficientes instrucciones específicas para la tarea implementadas en el hardware salvo un tráfico muy elevado no tiene por que notarse en gran medida el procesado de cada recurso. Si el tráfico fuese elevado y la carga de compresión se notase Nginx y Apache ofrecen la posibilidad de precomprimir los recursos y de forma similar precomprimir los recursos en apache.

La compresión es otra de las configuraciones básicas aconsejable hacer en un servidor web junto con:

  • Añadir cifrado y autenticación con TLS/SSL.
  • Añadir el soporte para el protocolo HTTP/2 que ya incluyen los navegadores.
  • Redirigir el tráfico del dominio raíz al subdominio www.
  • Redirigir el tráfico de HTTP a HTTPS.

Estas funcionalidades las puedes consultar en el resto de artículos de la serie web.

Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
./docker-nginx.sh o ./docker-httpd.sh


Comparte el artículo: