Auditoría de compresión y caché

Dos cabeceras de respuesta deciden cuántos bytes viajan en una primera visita y cuántos vuelven a viajar en la siguiente. Esta auditoría las lee en tu página y en hasta catorce de sus propios archivos.

O prueba mozilla.org, wordpress.org

Un breve intercambio en las cabeceras

Con cada petición, el navegador anuncia los formatos de compresión que sabe descomprimir:

Accept-Encoding: gzip, deflate, br, zstd

Un servidor con la compresión activada elige uno, reduce el archivo y etiqueta la respuesta con Content-Encoding: br (Brotli) o gzip. El HTML, el CSS y el JavaScript son texto repetitivo y suelen perder entre el 70 y el 85% de su tamaño. Los archivos JPEG, PNG, WebP, AVIF y WOFF2 ya vienen comprimidos por su propio formato, así que enviarlos tal cual es lo correcto.

El caché es la otra mitad. Cache-Control: max-age=31536000 deja que el navegador reutilice un archivo durante un año sin preguntar. Cuando caduca, una cabecera ETag o Last-Modified permite al navegador hacer una pregunta barata, “¿ha cambiado?”, y el servidor responde 304 Not Modified sin cuerpo.

Qué archivos se auditan

Empezamos por la propia página, después de las redirecciones, y luego tomamos archivos del mismo dominio registrado que aparezcan en su HTML: hasta cuatro hojas de estilo, cinco scripts, tres imágenes y dos fuentes. Los lugares que queden sin usar pasan a los demás archivos, hasta quince en total, y las fuentes que se citan dentro de tus hojas de estilo se añaden si hay sitio. Cada archivo se pide como lo haría un navegador, ofreciendo Brotli y gzip, y por HTTP/2 cuando el servidor lo admite.

Los archivos de otros dominios, como Google Fonts o un script de analítica, se dejan fuera. Sus cabeceras no las decides tú.

Cómo se juzga cada columna

Compresión
Verde cuando un archivo de texto llega con un Content-Encoding. Rojo cuando la página, o un archivo de texto de más de 20 KB, llega sin comprimir. Naranja para los archivos sin comprimir más pequeños, y no tomamos en cuenta los de menos de 1 KB. Para cada archivo sin comprimir, la auditoría lo comprime con gzip por su cuenta y muestra el tamaño que obtendrías. Las imágenes y las fuentes WOFF2 aparecen como “no necesario”.
Caché
La duración sale de max-age, o de Expires cuando no hay max-age. Una hoja de estilo, un script, una imagen o una fuente se marca cuando no tiene duración o la tiene menor de siete días. no-store y no-cache cuentan como cero. La página HTML se muestra solo a título informativo, con un aviso si puede conservarse más de una hora, porque entonces quienes vuelven podrían ver una versión desactualizada.
Protocolo
Aprueba con HTTP/2, que lleva todos los archivos en paralelo por una sola conexión. HTTP/3 se detecta por la cabecera alt-svc, donde el servidor anuncia h3.
Ahorro
Bytes transferidos frente a bytes descomprimidos para toda la muestra.

Un sitio que usa gzip en todas partes recibe una nota sobre Brotli, que deja los archivos de texto un 15 a 20% más pequeños. Tómalo como una mejora que planificar. Sin ella no hay ningún fallo.

Cómo configurarlo sin riesgos

Cuando hay algo que arreglar, el resultado incluye bloques listos para Apache y nginx. Detrás de una CDN como Cloudflare, la compresión se hace en el borde y las duraciones de caché son un ajuste del panel. En WordPress, los plugins de caché escriben las mismas reglas por ti.

Para la duración, una regla lo decide todo. Un caché largo solo es seguro si la dirección del archivo cambia cada vez que cambia su contenido. Las herramientas de compilación producen nombres como app.3f9a1c.js, y WordPress añade ?ver=6.8. Los archivos así pueden llevar:

Cache-Control: public, max-age=31536000, immutable

A los archivos con nombre fijo les conviene más entre una semana y un mes. Para el HTML, Cache-Control: no-cache guarda una copia y la comprueba con el servidor antes de cada uso.

A pesar de su nombre, no-cache significa “revalidar antes de usar”. La directiva que prohíbe guardar una copia es no-store, y le corresponde a las páginas con datos personales.

Para confirmar un cambio desde una terminal:

curl -sI -H "Accept-Encoding: br, gzip" https://example.com/ | grep -iE "content-encoding|cache-control"

Lo que la auditoría deja fuera

Es una muestra de quince archivos de una sola página, así que un problema que afecte solo a otra plantilla puede pasar inadvertido. No ofrece Zstandard. Lee max-age e ignora s-maxage, que solo concierne a los cachés compartidos. Y se salta los archivos que tu propia CDN sirve desde otro dominio. Cada archivo se descarga hasta 3 MB.

Preguntas frecuentes

¿Cómo compruebo si gzip o Brotli está activado en mi sitio?

Pide una página con una cabecera Accept-Encoding y busca Content-Encoding en la respuesta. Esta auditoría lo hace con la página y sus archivos principales, y el comando curl de arriba lo hace con una sola dirección.

¿Brotli es mejor que gzip?

Para texto, sí. Los archivos salen un 15 a 20% más pequeños, y todos los navegadores actuales lo aceptan por HTTPS. Gzip sigue siendo una buena base y la alternativa para clientes antiguos. Los servidores suelen activar ambos.

¿Qué Cache-Control debo usar para CSS y JavaScript?

Si el nombre del archivo o la cadena de consulta cambia con cada versión, public, max-age=31536000, immutable. Si el nombre nunca cambia, elige una duración más corta, como una semana, o los visitantes se quedarán con la versión antigua después de una actualización.

¿Hay que comprimir las imágenes con gzip?

No. JPEG, PNG, WebP y AVIF ya están comprimidos, y gzip gastaría tiempo de procesador para ahorrar casi nada. SVG es la excepción, porque es texto y se comprime muy bien.

¿Por qué faltan algunos de mis archivos en la tabla?

Solo revisamos los archivos del mismo dominio registrado que la página, quince como máximo. Los archivos servidos desde otro dominio y los que los scripts cargan más tarde no están en la muestra.

¿Necesito HTTP/3?

HTTP/2 es el paso que importa, y casi todos los hostings lo ofrecen. HTTP/3 ayuda sobre todo en conexiones móviles inestables, y la forma más sencilla de tenerlo es una CDN que lo active por defecto.