La recuperación de recursos a través de la red es lenta y costosa:
- Las respuestas grandes requieren muchos recorridos entre el navegador y el servidor.
- La página no se cargará hasta que se hayan descargado por completo todos los recursos críticos.
- Si una persona accede a tu sitio con un plan de datos móviles limitado, cada solicitud innecesaria de la red es un desperdicio de su dinero.
¿Cómo puedes evitar solicitudes de red innecesarias? La caché HTTP del navegador es tu primera línea de defensa. No es necesariamente el enfoque más potente o flexible, y tienes un control limitado sobre la vida útil de las respuestas almacenadas en caché, pero es eficaz, es compatible con todos los navegadores y no requiere mucho trabajo.
En esta guía, se muestran los conceptos básicos de una implementación eficaz de almacenamiento en caché HTTP.
Compatibilidad del navegador
En realidad, no hay una sola API llamada caché HTTP. Es el nombre general de una colección de APIs de plataformas web. Esas APIs son compatibles con todos los navegadores:
Cache-Control
ETag
Last-Modified
Cómo funciona la caché HTTP
Todas las solicitudes HTTP que realiza el navegador primero se enrutan a la caché del navegador para verificar si hay una respuesta válida almacenada en caché que pueda usarse para completar la solicitud. Si hay una coincidencia, se lee la respuesta desde la caché, lo que elimina la latencia de la red y los costos de datos que genera la transferencia.
El comportamiento de la caché HTTP se controla mediante una combinación de encabezados de solicitud y encabezados de respuesta. En una situación ideal, tendrás control sobre el código de tu aplicación web (que determinará los encabezados de la solicitud) y la configuración de tu servidor web (que determinará los encabezados de respuesta).
Consulta el artículo Almacenamiento en caché de HTTP de MDN para obtener una descripción general conceptual más detallada.
Encabezados de solicitud: Quédate con los valores predeterminados (generalmente)
Existen varios encabezados importantes que deben incluirse en las solicitudes salientes de tu aplicación web, pero el navegador casi siempre se encarga de configurarlos en tu nombre cuando realiza solicitudes. Los encabezados de solicitud que afectan la verificación de actualidad, como If-None-Match
y If-Modified-Since
, aparecen según la comprensión del navegador de los valores actuales en la caché HTTP.
Esto es una buena noticia, ya que puedes continuar incluyendo etiquetas como <img src="my-image.png">
en tu código HTML, y el navegador se encargará automáticamente del almacenamiento en caché HTTP, sin ningún esfuerzo adicional.
Encabezados de respuesta: Configura tu servidor web
La parte más importante de la configuración del almacenamiento en caché HTTP son los encabezados que agrega el servidor web a cada respuesta saliente. Todos los siguientes encabezados tienen en cuenta el comportamiento efectivo de almacenamiento en caché:
Cache-Control
El servidor puede mostrar una directivaCache-Control
para especificar cómo y durante cuánto tiempo el navegador y otras cachés intermedias deben almacenar la respuesta individual en caché.ETag
Cuando el navegador encuentra una respuesta almacenada en caché caducada, puede enviar un token pequeño (generalmente un hash del contenido del archivo) al servidor para verificar si el archivo ha cambiado. Si el servidor devuelve el mismo token, el archivo es el mismo y no es necesario volver a descargarlo.Last-Modified
Este encabezado tiene el mismo propósito queETag
, pero usa una estrategia basada en el tiempo para determinar si un recurso cambió, en lugar de la estrategia basada en el contenido deETag
.
Algunos servidores web tienen compatibilidad integrada para configurar esos encabezados de forma predeterminada, mientras que otros omiten los encabezados por completo a menos que los configures explícitamente. Los detalles específicos sobre cómo configurar los encabezados varían considerablemente según el servidor web que uses, por lo que debes consultar la documentación de tu servidor para obtener los detalles más precisos.
Para ahorrarte algo de búsqueda, aquí tienes instrucciones sobre cómo configurar algunos servidores web populares:
Omitir el encabezado de respuesta Cache-Control
no inhabilita el almacenamiento en caché HTTP. En cambio, los navegadores adivinan de manera efectiva qué tipo de comportamiento de almacenamiento en caché es el más adecuado para un tipo de contenido determinado. Es probable que quieras más control del que esto ofrece, así que tómate el tiempo para configurar los encabezados de respuesta.
¿Qué valores de encabezado de respuesta deberías usar?
Hay dos situaciones importantes que debes considerar cuando configures tu encabezados de respuesta del servidor web.
Almacenamiento en caché de larga duración para URLs con control de versiones
Supongamos que tu servidor indica a los navegadores que almacenen en caché un archivo CSS durante 1 año (Cache-Control: max-age=31536000
), pero el diseñador acaba de realizar una actualización de emergencia que debes implementar de inmediato. ¿Cómo notificas a los navegadores que actualicen el estado "inactivo" copia almacenada en caché del archivo? No puedes, al menos no sin cambiar la URL del recurso.
Una vez que el navegador almacene la respuesta en caché, se usará la versión almacenada en caché hasta que ya no esté actualizada, según lo determine max-age
o expires
, o hasta que se expulse de la caché por algún otro motivo (por ejemplo, cuando el usuario borre la caché de su navegador). Como resultado, diferentes usuarios pueden terminar usando diferentes versiones del archivo cuando se crea la página: los usuarios que acaban de recuperar el recurso usan la versión nueva, mientras que los que almacenaron en caché una copia anterior (pero aún válida) utilizan una versión anterior de su respuesta.
¿Cómo obtienes lo mejor de ambos mundos (almacenamiento en caché del cliente y actualizaciones rápidas)? Puedes cambiar la URL del recurso y obligar al usuario a descargar la nueva respuesta cada vez que cambie su contenido. Por lo general, esto se hace incorporando una huella digital del archivo, o un número de versión, en el nombre de archivo, por ejemplo, style.x234dff.css
.
Cuando se responden solicitudes de URLs que contienen "huella digital" o control de versiones, y cuyo contenido nunca está destinado a cambiar, agrega Cache-Control: max-age=31536000
a tus respuestas.
Configurar este valor le indica al navegador que, cuando necesite cargar la misma URL en cualquier momento durante el próximo año (31,536,000 segundos; el valor máximo admitido), puede usar de inmediato el valor de la Caché HTTP, sin tener que realizar una solicitud de red a tu servidor web en absoluto. Eso es fantástico. De inmediato, obtuviste la confiabilidad y la velocidad que se generan al evitar la red.
Las herramientas de compilación como webpack pueden automatizar el proceso de asignación de huellas digitales de hash a las URLs de tus recursos.
Revalidación del servidor para URLs sin versiones
Lamentablemente, no todas las URLs que cargas tienen control de versiones. Tal vez no puedas incluir un paso de compilación antes de implementar tu aplicación web, por lo que no puedes agregar hash a las URLs de tus recursos. Y todas las aplicaciones web necesitan archivos HTML; esos archivos (casi) nunca incluirán información sobre el control de versiones, ya que nadie se molestará en usar tu aplicación web si necesita recordar que la URL para visitar es https://example.com/index.34def12.html
. ¿Qué puedes hacer con esas URLs?
Esta es una situación en la que hay que admitir la derrota. El almacenamiento en caché HTTP por sí solo no es lo suficientemente potente para evitar la red por completo. (No te preocupes, pronto aprenderás sobre los trabajadores de servicio, que te brindarán la ayuda que necesitamos para devolver la batalla a tu favor). Sin embargo, puedes seguir algunos pasos para asegurarte de que las solicitudes de red sean lo más rápidas y eficientes posible.
Los siguientes valores de Cache-Control
pueden ayudarte a definir mejor dónde y cómo se almacenan en caché las URLs sin versiones:
no-cache
Esto le indica al navegador que debe volver a validarse con el servidor cada vez antes de usar una versión almacenada en caché de la URL.no-store
Esto indica al navegador y a otras cachés intermedias (como CDN) que nunca almacenen ninguna versión del archivo.private
Los navegadores pueden almacenar el archivo en caché, pero las intermedias no.public
La respuesta se puede almacenar en cualquier caché.
Consulta el Apéndice: Diagrama de flujo de Cache-Control
para visualizar el proceso de decisión de qué valores de Cache-Control
usar. Cache-Control
también puede aceptar una lista de directivas separada por comas. Consulta el Apéndice: Ejemplos de Cache-Control
.
Configurar ETag
o Last-Modified
también puede ayudar. Como se mencionó en los encabezados de respuesta, ETag
y Last-Modified
tienen el mismo propósito: determinar si el navegador debe volver a descargar un archivo almacenado en caché que venció. Te recomendamos que uses ETag
porque es más preciso.
Supongamos que ya pasaron 120 segundos desde la recuperación inicial y el navegador inició una solicitud nueva para el mismo recurso. Primero, el navegador verifica la caché HTTP y encuentra la respuesta anterior. Lamentablemente, el navegador no puede usar la respuesta anterior porque venció. En este punto, el navegador podría enviar una solicitud nueva y recuperar la respuesta completa nueva. Sin embargo, eso no es eficiente, ya que si el recurso no cambió, no hay motivo para descargar la misma información que ya está en la caché.
Ese es el problema que resuelven los tokens de validación, como se especifica en el encabezado ETag
. El servidor genera y muestra un token arbitrario, que normalmente es un hash o alguna otra huella digital del contenido del archivo. No es necesario que el navegador sepa cómo se genera la huella digital. solo necesita enviarlo al servidor
en la próxima solicitud. Si la huella digital sigue siendo la misma, significa que el recurso no ha cambiado y el navegador puede omitir la descarga.
Configurar ETag
o Last-Modified
hace que la solicitud de revalidación sea mucho más eficiente, ya que permite que active los encabezados de solicitud If-Modified-Since
o If-None-Match
que se mencionan en Encabezados de la solicitud.
Cuando un servidor web configurado correctamente detecta esos encabezados de la solicitud entrante, puede confirmar si la versión del recurso que el navegador ya tiene en su caché HTTP coincide con la última versión del servidor web. Si se detecta una coincidencia, el servidor puede responder con una respuesta HTTP 304 Not Modified
, que es el equivalente a "¡Sigue usando lo que ya tienes!". Hay muy pocos datos para transferir cuando se envía este tipo de respuesta, por lo que suele ser mucho más rápido que tener que devolver una copia del recurso real que se solicita.
Resumen
La Caché HTTP es una forma eficaz de mejorar el rendimiento de carga porque reduce las solicitudes de red innecesarias. Es compatible con todos los navegadores y su configuración no requiere demasiado trabajo.
Los siguientes parámetros de configuración de Cache-Control
son un buen comienzo:
Cache-Control: no-cache
para los recursos que se deben revalidar con el servidor antes de cada uso.Cache-Control: no-store
para recursos que nunca deben almacenarse en cachéCache-Control: max-age=31536000
para los recursos con control de versiones.
Y el encabezado ETag
o Last-Modified
puede ayudarte a revalidar los recursos de caché vencidos de manera más eficiente.
Más información
Si buscas ir más allá de los conceptos básicos del uso del encabezado Cache-Control
, consulta la guía Prácticas recomendadas de almacenamiento en caché y trampas de la edad máxima de Jake Archibald.
Consulta Te gusta tu caché si deseas obtener orientación sobre cómo optimizar el uso de la caché para los visitantes recurrentes.
Apéndice: Más sugerencias
Si tienes más tiempo, estas son otras formas de optimizar tu uso de la caché HTTP:
- Usa URLs coherentes. Si publicas el mismo contenido en URLs diferentes, ese contenido se recuperará y almacenará varias veces.
- Minimiza la deserción. Si parte de un recurso (como un archivo CSS) se actualiza con frecuencia, mientras que el resto del archivo no (como el código de la biblioteca), considera dividir el código que se actualiza con frecuencia en un archivo separado y usar una estrategia de almacenamiento en caché de corta duración para el código que se actualiza con frecuencia y una estrategia de duración de almacenamiento en caché larga para el código que no cambia con frecuencia.
- Consulta la nueva directiva
stale-while-revalidate
si tu políticaCache-Control
acepta algún grado de inactividad.
Apéndice: Diagrama de flujo de Cache-Control
Apéndice: Ejemplos de Cache-Control
Valor Cache-Control |
Explicación |
---|---|
max-age=86400 |
Los navegadores y los cachés intermedios pueden almacenar la respuesta en caché durante un máximo de 1 día (60 segundos x 60 minutos x 24 horas). |
private, max-age=600 |
El navegador puede almacenar la respuesta en caché (pero no las cachés intermedias) durante un máximo de 10 minutos (60 segundos x 10 minutos). |
public, max-age=31536000 |
La respuesta se puede almacenar en cualquier caché durante 1 año. |
no-store |
La respuesta no puede almacenarse en caché y debe recuperarse por completo en cada solicitud. |