Obtener recursos a través de la red es lento y costoso:
- Las respuestas grandes requieren muchos recorridos entre el navegador y el servidor.
- La página no se cargará hasta que todos sus recursos críticos se hayan descargado por completo.
- Si una persona accede a tu sitio con un plan limitado de datos móviles, cada solicitud de red innecesaria es una pérdida de 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 el ciclo de vida 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 API de plataformas web. Esas APIs son compatibles con todos los navegadores:
Cómo funciona la caché HTTP
Todas las solicitudes HTTP que realiza el navegador se enrutan primero a la caché del navegador para verificar si hay una respuesta válida almacenada en caché que se pueda usar para completar la solicitud. Si hay una coincidencia, la respuesta se lee 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 tanto del código de tu aplicación web (que determinará los encabezados de la solicitud) como de 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 la solicitud: Conserva los valores predeterminados (por lo general)
Si bien existen varios encabezados importantes que deben incluirse en las solicitudes salientes de tu app web, el navegador casi siempre se encarga de configurarlos por ti cuando realiza solicitudes. Los encabezados de solicitud que afectan la verificación
de actualización, como If-None-Match
y
If-Modified-Since
, solo aparecen según la comprensión del navegador
de los valores actuales de la caché HTTP.
Esta es una buena noticia, ya que significa que puedes continuar incluyendo etiquetas como <img
src="my-image.png">
en tu HTML, y el navegador se encarga automáticamente del almacenamiento en caché de HTTP, sin esfuerzo adicional.
Encabezados de respuesta: Configura tu servidor web
La parte más importante de la configuración del almacenamiento en caché de HTTP son los encabezados que agrega tu servidor web a cada respuesta saliente. Todos los encabezados siguientes influyen en el comportamiento efectivo del almacenamiento en caché:
Cache-Control
. El servidor puede mostrar una directivaCache-Control
para especificar cómo y por cuánto tiempo el navegador y otras memorias caché intermedias deben almacenar en caché la respuesta individual.ETag
. Cuando el navegador encuentra una respuesta almacenada en caché vencida, puede enviar un token pequeño (por lo general, un hash del contenido del archivo) al servidor para verificar si el archivo cambió. Si el servidor muestra el mismo token, entonces 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 oposición a la estrategia basada en el contenido deETag
.
Algunos servidores web tienen compatibilidad integrada para configurar esos encabezados de forma predeterminada, mientras que otros no los configuran por completo, a menos que los configures de forma explícita. Los detalles específicos sobre cómo configurar los encabezados varían mucho según el servidor web que uses y debes consultar la documentación de tu servidor para obtener los detalles más precisos.
A fin de ahorrarte algunas búsquedas, aquí encontrarás instrucciones para configurar algunos servidores web populares:
Dejar el encabezado de respuesta Cache-Control
no inhabilita el almacenamiento en caché HTTP.
En cambio, los navegadores adivinan de forma efectiva qué tipo de comportamiento de almacenamiento en caché tiene más sentido para un tipo determinado de contenido.
Es probable que quieras más control del que ofrece, así que tómate el tiempo para configurar tus encabezados de respuesta.
¿Qué valores de encabezado de respuesta deberías usar?
Hay dos situaciones importantes que debes cubrir cuando configuras los encabezados de respuesta de tu servidor web.
Almacenamiento en caché de larga duración para las URLs con versión
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 tu diseñador acaba de realizar una actualización de emergencia que debes lanzar de inmediato. ¿Cómo notificas a los navegadores para que actualicen la copia "inactiva" almacenada en caché del archivo?
No puedes hacerlo, al menos si no cambias la URL del recurso. Una vez que el navegador almacena en caché la respuesta, se usa la versión almacenada en caché hasta que ya no esté actualizada, según lo determinado por max-age
o expires
, o hasta que se expulse de la caché por algún otro motivo (por ejemplo, cuando el usuario borra la caché de su navegador). Como resultado, diferentes usuarios pueden terminar usando diferentes versiones del archivo cuando se construye la página: los usuarios que acaban de obtener el recurso usan la versión nueva, mientras que los usuarios que almacenaron en caché una copia anterior (pero aún válida) usan una versión anterior de su respuesta. ¿Cómo obtienes lo mejor de ambos mundos (almacenamiento en caché del cliente y actualizaciones rápidas)? Cambias la URL del recurso y obligas al usuario a descargar la respuesta nueva cada vez que cambia su contenido. Por lo general, se hace mediante la incorporación de una huella digital del archivo o un número de versión en el nombre de archivo, por ejemplo, style.x234dff.css
.
Cuando respondas solicitudes de URL que contienen "huella digital" o información sobre el control de versiones, y cuyo contenido nunca debe cambiar, agrega Cache-Control: max-age=31536000
a tus respuestas.
Establecer 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 el valor de la caché HTTP de inmediato, sin tener que realizar ninguna solicitud de red a tu servidor web. Eso es genial, ya que obtuviste de inmediato la confiabilidad y la velocidad que se genera cuando evitas 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 app web, por lo que no puedes agregar hashes a las URLs de tus elementos. Además, todas las aplicaciones web necesitan archivos HTML, esos archivos (casi) nunca incluirán información sobre el control de versiones, ya que nadie se interrumpirá en usar tu app web si necesita recordar que la URL para visitar es https://example.com/index.34def12.html
. Entonces, ¿qué puedes hacer para esas URLs?
Este es un escenario en el que debes admitir la derrota. El almacenamiento en caché de HTTP por sí solo no es lo suficientemente potente para evitar la red por completo. (No te preocupes, pronto aprenderás sobre los service workers, que nos brindarán el apoyo que necesitamos para inclinar la batalla a tu favor). Sin embargo, hay algunos pasos que puedes seguir 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 dónde y cómo se almacenan en caché las URLs sin versiones:
no-cache
. Esto indica al navegador que debe volver a validar con el servidor cada vez antes de usar una versión almacenada en caché de la URL.no-store
: Indica al navegador y a otras memorias caché intermedias (como CDN) que nunca almacenan versiones del archivo.private
: Los navegadores pueden almacenar en caché el archivo, pero no las cachés intermedias.public
. Cualquier caché puede almacenar la respuesta.
Consulta el Apéndice: Diagrama de flujo de Cache-Control
para visualizar el proceso
de decidir qué valores de Cache-Control
usar. Además, ten en cuenta que Cache-Control
puede aceptar una lista de directivas separadas por comas. Consulta el Apéndice: ejemplos de Cache-Control
.
Además, configurar uno de los dos encabezados de respuesta adicionales también puede ser útil: ETag
o Last-Modified
. Como se mencionó en 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ó. ETag
es el enfoque recomendado porque es más preciso.
Supongamos que ya pasaron 120 segundos desde la recuperación inicial y el navegador inició una nueva solicitud para el mismo recurso. Primero, el navegador revisa la caché HTTP y encuentra la respuesta anterior. Lamentablemente, el navegador no puede usar la respuesta anterior porque esta venció. En este punto, el navegador podría enviar una solicitud nueva y obtener la nueva respuesta completa. Sin embargo, no resulta 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 pueden resolver los tokens de validación, como se especifica en el encabezado ETag
. El servidor genera y muestra un token arbitrario que, por lo general, es un hash o alguna otra huella digital del contenido del archivo. El navegador no necesita saber cómo se genera la huella digital; solo debe enviarla al servidor en la próxima solicitud. Si la huella digital sigue siendo la misma, significa que el recurso no cambió y el navegador puede omitir la descarga.
Si configuras ETag
o Last-Modified
, lograrás que la solicitud de revalidación sea mucho más eficiente. Terminan activando los encabezados de solicitud If-Modified-Since
o If-None-Match
que se mencionaron en Encabezados de la solicitud.
Cuando un servidor web configurado de forma correcta ve esos encabezados de solicitudes entrantes, puede confirmar si la versión del recurso que el navegador ya tiene en su caché HTTP coincide con la versión más reciente del servidor web. Si hay una coincidencia,
el servidor puede responder con una respuesta HTTP 304 Not Modified
,
que es el equivalente de "Hey, sigue usando lo que ya tienes". Hay muy pocos datos para transferir cuando se envía este tipo de respuesta, por lo que, en general, el proceso es mucho más rápido que tener que enviar una copia del recurso real que se solicita.

/file
al servidor y, además, incluye el encabezado If-None-Match
para indicarle al servidor que solo muestre el archivo completo si el ETag
del archivo en el servidor no coincide con el valor If-None-Match
del navegador. En este caso, los 2 valores coincidieron, por lo que el servidor muestra una respuesta 304 Not Modified
con instrucciones sobre cuánto tiempo más se debe almacenar en caché el archivo (Cache-Control: max-age=120
).
Resumen
La caché HTTP es una forma eficaz de mejorar el rendimiento de la carga, ya que reduce las solicitudes de red innecesarias. Es compatible con todos los navegadores y no requiere mucho trabajo para su configuración.
Las siguientes configuraciones de Cache-Control
son un buen comienzo:
Cache-Control: no-cache
para los recursos que se deben volver a validar con el servidor antes de cada uso.Cache-Control: no-store
para los recursos que nunca se deben almacenar en cachéCache-Control: max-age=31536000
para 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 quieres 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 para la edad máxima de Jake Archibald.
Consulta Love your cache a fin de obtener orientación sobre cómo optimizar el uso de caché para los visitantes recurrentes.
Apéndice: Más sugerencias
Si tienes más tiempo, aquí tienes otras formas en las que puedes optimizar tu uso de la caché HTTP:
- Usa URLs coherentes. Si publicas el mismo contenido en diferentes URLs, 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 frecuentemente 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 prolongada para el código que no cambia con frecuencia.
- Revisa la nueva directiva
stale-while-revalidate
si es aceptable un cierto grado de inactividad en tu políticaCache-Control
.
Apéndice: Diagrama de flujo de Cache-Control
Apéndice: Cache-Control
ejemplos
Valor Cache-Control |
Explicación |
---|---|
max-age=86400 |
Los navegadores y las memorias caché intermedias 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 memorias caché intermedias) durante un máximo de 10 minutos (60 segundos x 10 minutos). |
public, max-age=31536000 |
Cualquier caché puede almacenar la respuesta durante 1 año. |
no-store |
No se puede almacenar la respuesta en caché y se debe recuperar por completo en cada solicitud. |