🚄 Activando HTTP/2 en Nginx para mejorar la velocidad del sitio web

Para poder servir páginas y aplicaciones web se requiere de un servidor HTTP (un protocolo de transferencia de hipertexto) que entregue el contenido generado por dichos sitios a los clientes.

Existen varias versiones del protocolo HTTP que han sido publicadas a lo largo de los años, cada una de estas versiones otorga ventajas sobre la anterior. HTTP/2 fue lanzado en 2015 trayendo consigo una gran mejora en los tiempos de carga de los sitios web, esto es debido a que:

  • HTTP/2 utiliza una sola conexión con el servidor para enviar y recibir datos en paralelo, contrario a la versión anterior que requería múltiples conexiones. En muchos casos el número de conexiones es de 6 a 10, lo cual implicaba que si un sitio web contiene 100 distintos elementos las peticiones para obtenerlos tenían que ser procesadas en varios bloques.
  • HTTP/2 no necesita esperar a que una petición termine para que otra comience.
  • HTTP/2 hace uso de compresión para enviar datos en las cabeceras de los mensajes, reduciendo el tamaño del mensaje.
  • HTTP/2 es un protocolo binario, los datos son codificados reduciendo también el tamaño del mensaje

HTTP/2 por lo tanto otorga una ventaja en eficiencia y velocidad de transferencia de los datos. Al activarlo no sólo mejoramos el rendimiento de nuestro sitio web sino que también afectamos de manera positiva la calificación de los buscadores como Google y la sustentabilidad de nuestros servicios.

Nginx es una implementación de servidor HTTP bastante potente y popular que utilizo para la mayoría de sitios y aplicaciones que mantengo y que soporta HTTP/2.

TLS, HTTPs y HTTP/2

Uno de los requerimientos de los navegadores para permitir el uso correcto de HTTP/2 es el uso de una conexión segura mediante TLS como mecanismo de encriptación de la información.

TLS funciona mediante certificados, si no cuentas con uno es recomendable que visites Let’s Encrypt para obtener uno dedicado a tu sitio web. Let’s Encrypt permite generar certificados verificados de forma sencilla sin tener que pagar a una entidad privada para obtener uno. Las instrucciones son fáciles de seguir e implementar, en mi caso hago uso de Certbot para obtener distintos certificados para los sitios y aplicaciones.

Habilitando HTTP/2

Certbot, además de generar el certificado, también escribe la configuración necesaria para NGINX de tal forma que el sitio web pueda servir HTTPs de forma inmediata. Lamentablemente esta configuración no habilita HTTP/2 por default (existe un reporte abierto por varios años sin resolver) por lo cual se requiere de una intervención manual para poder habilitarlo.

Primero debemos corroborar que el NGINX que tenemos instalado soporta HTTP/2

# como super usuario
; strings /usr/sbin/nginx | grep _module | grep -v configure| sort | grep ngx_http_v2_module

[...]
ngx_http_v2_module
ngx_http_v2_module

Una salida similar a la mostrada anteriormente nos permite corroborar el uso del protocolo.

Una vez hecho esto es simplemente se requiere una pequeña modificación en el archivo de configuración del sitio web para activar el protocolo. En este ejemplo usaremos misitio.com.conf como nombre de dicho archivo.

# como super usuario en una máquina Debian
; nano /etc/nginx/sites-available/misitio.com.conf
// misitio.com.conf
server {
        root /var/www/misitio;
        [...]
        listen [::]:443 ssl ipv6only=on http2; # managed by Certbot
        listen 443 ssl http2; # managed by Certbot
        [...]
}

El cambio requerido se aplica en las líneas de configuración correspondientes a SSL, agregando al final la especificación del uso de HTTP/2.

Una vez guardados los cambios es necesario reiniciar el servidor web.

# como super usuario

# comprobamos que la configuración sea correcta y reiniciamos el servidor
; nginx -t && service nginx restart

Verificando los cambios

Para comprobar la efectividad del cambio podemos hacer uso de curl para obtener los encabezados de nuestro sitio web. En dichos encabezados se encuentra la información del protocolo.

; curl -I https://misitio.com

HTTP/2 200
[...]

Como se observa ahora la respuesta incluye HTTP/2.