Cómo cachear recursos estáticos con Nginx para sitios más rápidos
Por qué importa el caché de recursos estáticos
Cada vez que un usuario visita tu sitio web, su navegador solicita decenas de recursos estáticos: archivos CSS, JavaScript, imágenes, fuentes y más. Sin un caché adecuado, cada solicitud llega a tu servidor, aumentando los tiempos de carga y el uso de ancho de banda. Nginx, un servidor web de alto rendimiento, puede mejorar esto drásticamente al indicar a los navegadores que cacheen estos recursos localmente y al cachearlos también en el servidor.
En esta guía, aprenderás a configurar Nginx para cachear recursos estáticos de forma eficaz, reduciendo la latencia y la carga del servidor.
Entender el caché del navegador vs. el caché del servidor
Hay dos tipos principales de caché relevantes aquí:
- Caché del navegador: el navegador almacena los recursos localmente según cabeceras HTTP como
Cache-ControlyExpires. Las visitas posteriores cargan los recursos desde el disco, evitando solicitudes de red. - Caché del servidor: Nginx almacena las respuestas en memoria o disco y las sirve directamente para solicitudes repetidas, reduciendo la carga del backend.
Ambos son cruciales para el rendimiento. Cubriremos los dos.
Paso 1: Configurar el caché del navegador con cabeceras Expires
La forma más sencilla de habilitar el caché del navegador es añadir directivas expires a tu configuración de Nginx. Esto establece las cabeceras Expires y Cache-Control.
Abre el archivo de configuración de tu sitio (por ejemplo, /etc/nginx/sites-available/example.com) y añade un bloque location para recursos estáticos:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
Esto indica al navegador que cachee estos archivos durante un año. La directiva immutable indica que el archivo nunca cambiará, por lo que el navegador ni siquiera revalidará al recargar.
Buena práctica: usa nombres de archivo versionados (por ejemplo, style.abc123.css) para poder actualizar los recursos sin romper el caché. Cuando el archivo cambia, el nombre cambia y el navegador obtiene la nueva versión.
Paso 2: Habilitar el caché del servidor con Proxy Cache
Si ejecutas un servidor de aplicaciones (como Node.js, Python o PHP) detrás de Nginx, puedes cachear las respuestas estáticas en Nginx para reducir las solicitudes al backend.
Primero, define una ruta de caché en el bloque http de nginx.conf:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=60m use_temp_path=off;
Después, en tu bloque server, úsala:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
proxy_cache static_cache;
proxy_cache_valid 200 302 1y;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
Esto cachea las respuestas exitosas durante un año y sirve contenido obsoleto si el backend está caído. La cabecera X-Cache-Status te ayuda a depurar (HIT, MISS, etc.).
Paso 3: Optimizar con compresión y HTTP/2
El caché reduce las solicitudes, pero puedes acelerar aún más las transferencias habilitando la compresión gzip y HTTP/2.
Habilita gzip en nginx.conf:
gzip on;
gzip_types text/css application/javascript image/svg+xml;
gzip_min_length 1000;
HTTP/2 multiplexa las solicitudes y se habilita añadiendo http2 a tu directiva listen:
listen 443 ssl http2;
Nota: HTTP/2 requiere HTTPS. Si aún no has configurado TLS, consulta nuestra guía sobre cómo funcionan realmente HTTPS y TLS.
Comparación: directivas de Cache-Control
| Directiva | Significado | Recomendada para |
|---|---|---|
public |
La respuesta puede ser cacheada por cualquier caché | Recursos estáticos |
private |
La respuesta es para un solo usuario | Datos específicos del usuario |
no-cache |
Debe revalidarse con el servidor | Páginas HTML |
no-store |
Nunca cachear | Datos sensibles |
immutable |
El contenido no cambiará | Recursos versionados |
Paso 4: Probar y verificar
Después de aplicar los cambios, recarga Nginx: sudo nginx -s reload. Luego prueba con curl:
curl -I https://example.com/style.css
Busca las cabeceras Cache-Control y Expires. También puedes usar las DevTools del navegador (pestaña Network) para ver si los recursos se sirven desde el caché (Estado 200 o 304).
Para el caché del servidor, monitoriza la cabecera X-Cache-Status.
Errores comunes y buenas prácticas
- No cachees HTML: el HTML debe ser dinámico o tener tiempos de caché cortos para reflejar las actualizaciones.
- Usa versionado: añade hashes a los nombres de archivo para invalidar el caché cuando el contenido cambie.
- Establece un max-age adecuado: un año es seguro para recursos versionados.
- Monitoriza el tamaño del caché: los cachés del servidor pueden crecer; configura
max_sizeeinactive. - Considera una CDN: para audiencias globales, una CDN puede cachear recursos más cerca de los usuarios.
Preguntas frecuentes
¿Cómo sé si mis recursos se están cacheando?
Revisa las cabeceras de respuesta con curl -I o las DevTools del navegador. Busca Cache-Control: public, max-age=31536000 y las cabeceras Expires. En DevTools, la columna Size mostrará "(from disk cache)" para los recursos cacheados.
¿Cuál es la diferencia entre expires y Cache-Control?
expires establece una fecha absoluta, mientras que Cache-Control usa segundos relativos. Cache-Control tiene prioridad en los navegadores modernos. La directiva expires de Nginx establece ambas por compatibilidad.
¿Puedo cachear contenido dinámico?
Sí, pero con precaución. Usa proxy_cache con TTLs cortos y considera claves de caché basadas en cookies o cabeceras. Para contenido específico del usuario, usa private o evita el caché.
Acelera tu flujo de trabajo con TryQuickToolBox
Mientras optimizas el rendimiento de tu sitio, puede que necesites comprimir imágenes o PDFs. Prueba nuestro Compresor de Imágenes para reducir el tamaño de las imágenes sin perder calidad, complementando tu estrategia de caché de Nginx.