DEV Community

Cover image for Nginx keepalive, gzip, http2: mejor rendimiento en tu sitio web
Eduardo Zepeda
Eduardo Zepeda

Posted on • Originally published at coffeebytes.dev

Nginx keepalive, gzip, http2: mejor rendimiento en tu sitio web

Hace algunos meses estaba revisando los valores de Lighthouse para un sitio web cuando me di cuenta de que no cumplia con ciertas recomendaciones, usaba http/1.1, no contaba con compresión gzip, ni cache. Más tarde arreglé los problemas, te cuento como a continuación. En esta entrada te platico sobre las siguientes características de nginx: keepalive, gzip, cache y http2 y como puedes modificarlas para mejorar tus valores de Lighthouse.

http2 en nginx

Por más sorprendente que suene, muchos servidores no habilitan HTTP/2 por defecto, por lo que, si es tu caso, puedes habilitarlo para tener un mejor rendimiento. El protocolo HTTP/2 es más eficiente que HTTP/1, por lo que obtendremos mejores indicadores usándolo.

Primero vamos al archivo donde tenemos habilitado nuestro sitio web en nginx:

sudo vim /etc/nginx/sites-enabled/mi-sitio
Enter fullscreen mode Exit fullscreen mode

Una vez en el archivo vamos a agregar http2 al final de nuestra directiva listen, en este caso en el puerto 443, por el HTTPS. Si sirves tu contenido sin usar HTTPS puedes agregarlo al puerto 80.

# /etc/nginx/sites-enabled/mi-sitio
server { 
    listen 443 ssl http2; 
    listen [::]:443 ssl http2;
    # ...
}
Enter fullscreen mode Exit fullscreen mode

Recuerda que tras cada cambio que hagamos será necesario recargar nginx para que adopte los nuevos valores.

sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Si ahora hacemos una petición a nuestro sitio web podremos corroborar si nuestro contenido se está sirviendo con el protocolo HTTP/2

curl https://tu-sitio-web.com -i
# ...
HTTP/2 200 
server: nginx
# ... 
Enter fullscreen mode Exit fullscreen mode

habilitar compresión gzip en nginx

La compresión gzip nos permite reducir el tamaño de los recursos que mandamos, tampoco suele venir habilitada por defecto.

Para habilitarla vamos a modificar el archivo de configuración de nginx. Recuerda que también puedes habilitarlas individualmente dentro de la directiva http en cada sitio web, pero para este caso colocaremos el cache de manera universal.

vim /etc/nginx/nginx.conf
Enter fullscreen mode Exit fullscreen mode

Si nos dirigimos a la sección de Gzip veremos varios valores comentados.

# /etc/nginx/nginx.conf
# ...

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 min_length 256;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss;
Enter fullscreen mode Exit fullscreen mode

Entre los valores comentados están la longitud mínima para comprimir, el nivel de compresión, si queremos aplicar compresión para solicitudes de un proxy, los tipos MIME que recibirán compresión y otras opciones.

Vamos a descomentarlos todas. Además agregaremos unos cuantos tipos MIME a la opción gzip_types.

# /etc/nginx/nginx.conf
# ...

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 min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon image/jpg image/png;
Enter fullscreen mode Exit fullscreen mode

Recuerda que puedes consultar todos los tipos MIME disponibles de manera amigable haciendo un bat o un cat al siguiente archivo:

sudo bat /etc/nginx/mime.types
Enter fullscreen mode Exit fullscreen mode

Ahora ya solo necesitas colocar los que consideres convenientes para tu aplicación. Recuerda también que usar la compresión hace más ligera la transferencia al usuario pero aumenta la carga del servidor al comprimir, por lo que tienes que evaluar que te conviene comprimir y que no.

Si haces un curl a alguno de los recursos para los que habilitaste compresión con el header "Accept-Encoding: gzip" podrás apreciar que la respuesta vendrá comprimida. Recuerda recargar el servidor para que los cambios surtan efecto.

curl -H "Accept-Encoding: gzip" https://tu-sitio-web.com
# ...
x-frame-options: DENY
x-content-type-options: nosniff
content-encoding: gzip
Enter fullscreen mode Exit fullscreen mode

nginx keepalive

El valor de configuración de nginx, keepalive_timeout, le dice al servidor cuanto tiempo debe mantener activa la conexión TCP para múltiples respuestas HTTP.

Sobre simplificando este concepto, podemos encontrar una similitud entre una conexión TCP y una llamada telefónica. Imaginemos dos escenarios:

El primer escenario es el siguiente: te piden que cuides a tus sobrinos y tus preocupados hermanos necesitan que les confirmes en voz viva, cada dos horas, que todo está bien. No tendría sentido llamar por teléfono y mantener la llamada toda la noche solo para estar diciéndoles "todo está bien" cada dos horas, es mejor colgar y repetir la llamada pasado ese tiempo. Así no mantenemos la linea ocupada. Es decir, lo mejor es llamar, confirmar que todo está bien y colgar.

El segundo escenario va así: estás hablando con tu mejor amiga, tienes muchísimas cosas que contarle, por lo que la llamas, la llamada dura mucho tiempo y, todo el tiempo están intercambiando mensajes, uno tras otro. No tendría sentido colgar y llamar entre cada intercambio de mensajes, es mejor mantenerla hasta que le hayas contado (y ella a ti) todo lo que tengas que decirle.

El valor de nginx keepalive será la duración de esta llamada, en el primer escenario es corto, en el segundo largo. ¿Cuál es mejor? ese valor debes decidirlo tú, con base en el comportamiento de tus usuarios, el valor por defecto es 75, yo usaré un 65.

# /etc/nginx/nginx.conf
keepalive_timeout 65;
Enter fullscreen mode Exit fullscreen mode

Cache

Usar cache puede mejorar enormemente el rendimiento de tu servidor. Para habilitar cache basta con agregar la palabra expires, seguido de la duración a los recursos que queremos colocar en cache.

location /static/ {
    root /app/static/;
    expires 30d; # También hubiera funcionado 1M
Enter fullscreen mode Exit fullscreen mode

Yo he colocado 30 días, pero puedes usar cualquier otro valor que prefieras.

Abreviación Significado
ms milisegundos
s segundos
m minutos
h horas
d días
w semanas
M Meses, 30 días
y Años, 365 días

Información tomada de la documentación oficial http://nginx.org/en/docs/syntax.html

Si haces una petición web a la ruta que está siendo cacheada deberías recibir una cabecera cache-control con el tiempo en segundos que especificaste (En mi caso 2592000 segundos, que son 30 días). Asegúrate de recargar el servidor.

curl -I https://tu-sitio-web.com/static/imagen.jpg
cache-control: max-age=2592000
Enter fullscreen mode Exit fullscreen mode

¿Te gustaría leer más contenido como este?

Haz click aquí

Top comments (0)