Supongamos que una biblioteca cambia el horario de hoy en su web, pero algunos visitantes siguen viendo el anterior. Primero hay que separar las posibles causas: ¿no se actualizó el original del servidor, el navegador reutilizó una respuesta guardada o un servidor intermedio entregó una versión antigua? Actualizar la pantalla varias veces no basta para saber en qué etapa está el problema.
Una caché HTTP guarda respuestas recibidas y las reutiliza cuando se cumplen las condiciones. Este artículo relaciona las instrucciones de almacenamiento y revalidación de Cache-Control con ETag y las respuestas 304 mediante un horario público ficticio. Los intercambios siguientes son ejemplos abreviados para explicar el funcionamiento, no mediciones de una biblioteca real ni de un servidor concreto. El objetivo es explicar qué respuestas deberían poder reutilizarse y cuándo, en vez de recomendar eliminar todas las cachés.
1. Separar almacenamiento, comprobación y uso compartido
Al leer una política de caché, anote tres preguntas por separado: ¿se puede guardar la respuesta, se puede usar directamente la copia en la siguiente solicitud y se puede compartir entre usuarios? Poder almacenarla no implica poder reutilizarla siempre; comprobar su vigencia tampoco concede permiso para compartirla. El estándar de caché HTTP RFC 9111 define estas condiciones con directivas distintas. Aquí se explican las directivas de respuesta sin un argumento adicional con nombres de campos.
| Pregunta que decidir | Directiva de respuesta relacionada | Significado que distinguir |
|---|---|---|
| ¿Debe prohibirse guardar la respuesta? | no-store | Prohíbe almacenarla para reutilizarla después |
| ¿Hay que comprobarla antes de reutilizarla? | no-cache | Puede almacenarse, pero exige validación satisfactoria antes de reutilizarla |
| ¿Pueden compartirla varios usuarios? | private | Excluye el almacenamiento en cachés compartidas, sin prohibirlo también en una caché privada |
Por ejemplo, para un horario público que se edita con frecuencia en la misma dirección, puede considerarse la necesidad de comprobarlo antes de usar una copia guardada. Una pantalla personalizada ya difiere de ese horario en las condiciones de uso compartido. private se refiere a las cachés compartidas; no sustituye el inicio de sesión ni los controles de autorización. Mezclar ajustes con finalidades distintas en una frase puede llevar a definir mal el destinatario de la información al intentar mejorar la velocidad.
En la tabla de políticas, escriba también el motivo de cada directiva. Indique si el horario es información pública cuyos cambios deben comprobarse, si el logotipo es un archivo de contenido fijo o si una misma dirección contiene información diferente para cada persona. La tabla es un punto de partida para clasificar respuestas reales, no una configuración acabada aplicable a todas las webs. Distinga también el almacén al que se aplica, como el navegador o una CDN.
2. No elegir no-cache y no-store solo por sus nombres
Es fácil interpretar no-cache como una prohibición de almacenar. Sin embargo, en una respuesta exige validar la copia antes de reutilizarla. Si el servidor confirma que no ha cambiado, puede volver a utilizarse el cuerpo guardado. En cambio, no-store indica que no se guarde esta respuesta. Difieren tanto en qué puede conservarse como en qué debe comprobarse en la siguiente solicitud; no espere que funcionen igual.
En una caché, fresh significa que la política permite reutilizar sin validación adicional. No garantiza que el operador no haya cambiado el original mientras tanto. Si max-age define un período de reutilización, una respuesta ya guardada puede seguir seleccionándose aunque el original cambie dentro de ese plazo. Determine primero el retraso de actualización aceptable y relacione ese requisito con las directivas. No copie un plazo largo arbitrario como solución universal de rendimiento.
La guía de caché HTTP de MDN explica que añadir no-store a una respuesta nueva no borra las respuestas antiguas ya guardadas para la misma URL. Si la copia anterior sigue siendo utilizable y no se solicita una nueva respuesta, puede que ni siquiera llegue la nueva cabecera. No interprete no-store como un vaciado completo de caché ni como condición suficiente de privacidad. Revise también la vida de las respuestas existentes y el procedimiento de actualización de las cachés que puede controlar.
3. Seguir una nueva visita con ETag y 304
Imaginemos que la dirección ficticia /hours.json anuncia al principio un cierre a las 18:00. El siguiente ejemplo explicativo en formato HTTP/1.1 conserva solo las partes necesarias y omite otras cabeceras que una respuesta real necesitaría. hours-v1 es aquí un identificador de representación elegido por el servidor, no una fórmula para calcular horas ni el hash real de un archivo.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache
ETag: "hours-v1"
{"closes":"18:00"}
Si el navegador guardó esta respuesta, puede enviar después el valor ETag en If-None-Match dentro de una solicitud condicional. Si la condición coincide con la representación actual seleccionada por el servidor y este la considera inalterada, responde 304 Not Modified. El siguiente bloque es un registro abreviado que coloca consecutivamente una solicitud y su respuesta. No muestra un JSON de horario nuevo enviado después del 304.
GET /hours.json HTTP/1.1
Host: library.example
If-None-Match: "hours-v1"
HTTP/1.1 304 Not Modified
Cache-Control: no-cache
ETag: "hours-v1"
Como explica la documentación de ETag de MDN, en ese caso el cliente utiliza el cuerpo guardado. El 304 no incluye un cuerpo nuevo, pero la solicitud y la validación sí implican comunicación. Si el operador cambia el cierre a las 19:00 y también cambia la representación del servidor, cabe esperar que la condición antigua reciba un 200 con un cuerpo y un identificador nuevos. Usar no-cache no implica obtener siempre 304 ni eliminar las consultas a la base de datos.
Compruebe la correspondencia entre contenido e identificador, no solo el código de estado. Si cambia el contenido pero el servidor sigue utilizando el antiguo ETag, la validación puede dar un resultado incorrecto. Por el contrario, si el identificador cambia continuamente para contenido idéntico, pueden aumentar los reenvíos del cuerpo. Hay que revisar en el servidor la relación entre la generación del identificador y la representación elegida. Ver un ETag no demuestra por sí solo que la implementación sea correcta.
4. Distinguir documentos cambiantes y recursos con nombres nuevos
Un documento cuyo contenido cambia en la misma URL, como el horario, puede necesitar una estrategia distinta de la de un logotipo o script que recibe otro nombre cuando cambia. Si un logotipo pasa de logo.a1.png a logo.b2.png, el nuevo documento debe señalar la nueva dirección. Poner un identificador en el nombre pero sobrescribir después el contenido del archivo antiguo rompe el compromiso de gestionar conjuntamente contenido y dirección.
Subir un archivo nuevo no hace por sí solo que los visitantes soliciten su nueva dirección. Si el HTML que reciben sigue señalando el logotipo antiguo, pueden reutilizar el recurso anterior. Examine, por tanto, cómo se actualiza el documento que lo referencia, además de la configuración de caché del recurso. En vez de asignar el mismo tiempo de conservación a documentos y recursos, debe poder explicar cuánto retraso es admisible en cada uno.
Durante un despliegue pueden coexistir temporalmente documentos antiguos y nuevos. Publicar el nuevo documento antes de preparar sus recursos, o borrar demasiado pronto los antiguos, produce fallos distintos. En este ejemplo ficticio pueden comprobarse tanto la existencia de los archivos referenciados por el documento nuevo como el acceso a los que aún usan los documentos anteriores. Renombrar archivos es una herramienta del diseño de caché; no resuelve automáticamente todo problema de orden de despliegue o reversión.
5. Comprobar una hipótesis cada vez en Network
Para investigar directamente, registre primero una referencia con la caché permitida. Examine juntas la URL exacta y sus parámetros de consulta, la versión del horario mostrada, el estado de respuesta, If-None-Match en la solicitud y Cache-Control y ETag en la respuesta. Aunque sus nombres coincidan, las cabeceras de solicitud y respuesta expresan condiciones de participantes distintos; anote qué lado está leyendo. La referencia de Network de Chrome DevTools explica cómo distinguirlas en Headers.
| Situación de prueba ficticia | Registros que observar juntos | Conclusión prematura que evitar |
|---|---|---|
| Solicitar otra vez el mismo horario | Solicitud condicional, estado y horas mostradas | Un 304 significa que no hubo comunicación |
| Solicitar tras modificar el horario original | Cuerpo nuevo, ETag y URL realmente solicitada | El aviso de guardado correcto significa que todos los usuarios recibieron el cambio |
| Solicitar con la caché del navegador desactivada | Diferencia entre descarga inicial y revisita normal | El resultado equivale al rendimiento habitual de una revisita |
| Volver con el botón Atrás | Existencia de una nueva solicitud y pantalla restaurada | Ver la pantalla prueba que hubo una nueva validación HTTP |
Después pruebe la desactivación de la caché del navegador como condición separada. Disable cache de Chrome se aplica mientras DevTools está abierto; registre tanto la apertura de las herramientas como el ajuste. Sirve para examinar una descarga inicial, pero no es la misma prueba que observar cómo una revisita normal utiliza copias guardadas. Sin registrar el ajuste, recibir siempre una descarga nueva puede confundirse con que la caché no funciona. Conserve las condiciones para volver a comparar con la caché permitida.
Para acotar la causa, evite realizar muchas modificaciones y solicitudes a la vez. Primero compruebe una revisita sin cambiar el contenido y después cambie una sola hora para observar la respuesta. Si modifica simultáneamente la URL del documento, los ajustes del servidor y los nombres de archivo, será difícil separar el efecto de cada cambio. Si no obtiene el 200 o 304 previsto, relea la solicitud y la respuesta reales antes de añadir más ajustes.
6. Revisar otros almacenamientos y el criterio de finalización
Desactivar la caché HTTP del navegador no elimina necesariamente la CDN situada ante el servidor ni otras vías de almacenamiento de la aplicación. Revise por separado si un service worker atiende la solicitud, qué respuesta selecciona un servidor intermedio y si la aplicación mantiene en pantalla datos ya recibidos. Que aparezca la misma URL no implica que todas las capas utilicen la misma copia.
También hay que distinguir volver atrás de realizar una solicitud HTTP nueva. Cuando el navegador restaura una pantalla de una sesión anterior, puede no aparecer la revalidación esperada aunque exista no-cache. Tomarlo inmediatamente como prueba de que el servidor ignoró la cabecera puede señalar una causa equivocada. Registre si realmente hubo solicitudes al navegar de nuevo, recargar y volver atrás, para no agrupar fenómenos distintos como un solo problema.
El criterio de éxito del horario no es simplemente una buena tasa de aciertos de caché. Compruebe que se aprovecha bien la copia sin cambios, que la información nueva aparece dentro del plazo permitido y que se comparte con el público correcto. Anotar el momento de modificación y observación, las condiciones y el cuerpo real facilita que otra persona reproduzca el caso. Mejorar las cifras de velocidad no satisface el requisito original si se siguen viendo horarios incorrectos demasiado tiempo.
En producción, revise las políticas por tipo de respuesta junto con los procedimientos de actualización y reversión. No copie instrucciones de documentos públicos a respuestas personales ni interprete una validación satisfactoria como un control de acceso ya terminado. Las cabeceras transmiten reglas para almacenar y reutilizar. Poder explicar qué se guardó y qué comprobaciones condujeron a la pantalla actual permite diagnosticar mejor las pantallas desactualizadas.