Los usuarios que carguen tu sitio por segunda vez usarán su caché HTTP, así que asegúrate de que funcione bien.
Esta publicación es complementaria del video Ama tu caché, parte del contenido extendido de la Cumbre de desarrolladores de Chrome 2020. Asegúrate de mirar el siguiente video:
Cuando los usuarios carguen tu sitio por segunda vez, su navegador usará recursos dentro de su caché HTTP para ayudar a que esa carga sea más rápida. Sin embargo, los estándares para el almacenamiento en caché en la Web datan de 1999 y se definen de manera bastante amplia. Determinar si un archivo, como CSS o una imagen, se puede recuperar de la red en lugar de cargarse desde la caché es una ciencia un poco inexacta.
En esta publicación, hablaré sobre una configuración predeterminada moderna y sensata para la caché, que en realidad no usa la caché en absoluto. Pero esa es la configuración predeterminada y tiene más matices que solo "desactivarla". Sigue leyendo para conocer todos los detalles.
Objetivos
Cuando un sitio se carga por segunda vez, tienes dos objetivos:
- Asegúrate de que tus usuarios obtengan la versión más actualizada disponible. Si cambiaste algo, debería reflejarse rápidamente.
- Realiza el primer paso mientras recuperas lo menos posible de la red
En el sentido más amplio, solo quieres enviar el cambio más pequeño a tus clientes cuando vuelvan a cargar tu sitio. Además, estructurar el sitio para garantizar la distribución más eficiente de cualquier cambio es todo un desafío (encontrarás más información sobre esto a continuación y en el video).
Dicho esto, también tienes otros controles cuando consideras la caché. Quizás decidas permitir que la caché HTTP del navegador de un usuario retenga tu sitio durante mucho tiempo para que no se requieran solicitudes de red para entregarlo. O bien compilaste un service worker que publicará un sitio completamente sin conexión antes de verificar si está actualizado. Esta es una opción extrema, válida, y se usa para muchas experiencias web similares a las de las apps que priorizan el uso sin conexión, pero no es necesario que la Web esté en un extremo de solo caché, ni siquiera en un extremo completamente solo de red.
Segundo plano
Como desarrolladores web, todos estamos acostumbrados a la idea de tener una "caché inactiva". Sin embargo, sabemos, casi de forma instintiva, qué herramientas están disponibles para resolverlo: realiza una "actualización forzada", abre una ventana de incógnito o usa alguna combinación de las herramientas para desarrolladores de tu navegador a fin de borrar los datos de un sitio.
Los usuarios normales de Internet no tienen ese lujo. Por lo tanto, si bien tenemos algunos objetivos principales para garantizar que nuestros usuarios disfruten de la 2ª carga, también es muy importante asegurarnos de que no tengan una mala experiencia o se bloqueen. (Mira el video si quieres escucharme hablar sobre cómo casi logramos que el sitio web.dev/live se atasque).
A modo de referencia, un motivo muy común de la "caché inactiva" es, en realidad, la configuración predeterminada de la caché de la era de 1999. Se basa en el encabezado Last-Modified
:
Cada archivo que cargas se conserva durante un 10% adicional de su vida útil actual, tal como lo ve tu navegador. Por ejemplo, si index.html
se creó hace un mes, tu navegador lo almacenará en caché durante otros tres días.
Esta era una idea bien intencionada en su momento, pero, debido a la naturaleza de integración estrecha de los sitios web actuales, este comportamiento predeterminado significa que es posible llegar a un estado en el que un usuario tenga archivos diseñados para diferentes versiones de tu sitio web (p. ej., el JS de la versión del martes y el CSS de la versión del viernes), todo porque esos archivos no se actualizaron exactamente al mismo tiempo.
La ruta bien iluminada
Una configuración predeterminada moderna para el almacenamiento en caché es no almacenar en caché en absoluto y usar CDN para acercar tu contenido a los usuarios. Cada vez que un usuario cargue tu sitio, irá a la red para ver si está actualizado. Esta solicitud tendrá una latencia baja, ya que la proporcionará una CDN ubicada geográficamente cerca de cada usuario final.
Puedes configurar tu host web para que responda a las solicitudes web con este encabezado:
Cache-Control: max-age=0,must-revalidate,public
Esto básicamente indica que el archivo no es válido en ningún momento y que debes validarlo desde la red para poder volver a usarlo (de lo contrario, solo se "sugiere").
Este proceso de validación es relativamente económico en términos de bytes transferidos (si un archivo de imagen grande no cambió, tu navegador recibirá una pequeña respuesta 304), pero tiene un costo de latencia, ya que el usuario aún debe ir a la red para averiguarlo. Y esta es la desventaja principal de este enfoque. Puede funcionar muy bien para quienes tienen conexiones rápidas en el primer mundo y donde la CDN que elijas tiene una gran cobertura, pero no para quienes tienen conexiones móviles más lentas o una infraestructura deficiente.
Independientemente, este es un enfoque moderno que es el predeterminado en una CDN popular, Netlify, pero se puede configurar en casi cualquier CDN. En Firebase Hosting, puedes incluir este encabezado en la sección de hosting de tu archivo firebase.json:
"headers": [
// Be sure to put this last, to not override other headers
{
"source": "**",
"headers": [ {
"key": "Cache-Control",
"value": "max-age=0,must-revalidate,public"
}
}
]
Entonces, si bien sugiero que esto sea un valor predeterminado razonable, es solo eso, ¡el valor predeterminado! Sigue leyendo para descubrir cómo intervenir y actualizar los valores predeterminados.
URLs con huellas digitales
Si incluyes un hash del contenido del archivo en el nombre de los elementos, las imágenes y otros elementos que se publiquen en tu sitio, puedes asegurarte de que estos archivos siempre tendrán contenido único, lo que generará archivos llamados sitecode.af12de.js
, por ejemplo. Cuando tu servidor responde a las solicitudes de estos archivos, puedes configurar los navegadores de los usuarios finales para que los almacenen en caché durante mucho tiempo de forma segura con este encabezado:
Cache-Control: max-age=31536000,immutable
Este valor es un año, en segundos. Y, según las especificaciones, esto equivale a “para siempre”.
Es importante destacar que no debes generar estos hashes a mano, ya que es demasiado trabajo manual. Puedes usar herramientas como Webpack, Rollup, etcétera, para ayudarte con esto. Asegúrate de obtener más información sobre ellos en el Informe de herramientas.
Recuerda que no solo JavaScript puede beneficiarse de las URLs con huellas digitales. Los elementos como íconos, CSS y otros archivos de datos inmutables también se pueden nombrar de esta manera. (y asegúrate de mirar el video anterior para obtener más información sobre la división de código, que te permite enviar menos código cada vez que cambia tu sitio).
Independientemente de cómo tu sitio aborde el almacenamiento en caché, estos tipos de archivos con huellas digitales son muy valiosos para cualquier sitio que puedas compilar. La mayoría de los sitios no cambian en cada versión.
Por supuesto, no podemos cambiar el nombre de nuestras páginas "amigables" para el usuario de esta manera: cambiar el nombre de tu archivo index.html
a index.abcd12.html
. Eso es inviable y no puedes decirles a los usuarios que vayan a una nueva URL cada vez que cargan tu sitio. Estas URLs "amigables" no se pueden cambiar de nombre ni almacenar en caché de esta manera, lo que me lleva a un posible punto medio.
El punto medio
Obviamente, hay espacio para un término medio en lo que respecta a la caché. Te presenté dos opciones extremas: almacenar en caché nunca o almacenar en caché para siempre. Y habrá una serie de archivos que quizás quieras almacenar en caché por un tiempo, como las URL "fáciles" que mencioné antes.
Si quieres almacenar en caché estas URLs "amigables" y su código HTML, vale la pena considerar qué dependencias incluyen, cómo se pueden almacenar en caché y cómo podría afectarte almacenar en caché sus URLs durante un tiempo. Analicemos una página HTML que incluya una imagen como la siguiente:
<img src="/images/foo.jpeg" loading="lazy" />
Si actualizas o cambias tu sitio borrando o cambiando esta imagen cargada de forma diferida, es posible que los usuarios que vean una versión almacenada en caché de tu HTML obtengan una imagen incorrecta o que no esté, ya que aún tendrán almacenada en caché la /images/foo.jpeg
original cuando vuelvan a visitar tu sitio.
Si tienes cuidado, es posible que esto no te afecte. Sin embargo, en términos generales, es importante recordar que tu sitio, cuando los usuarios finales lo almacenan en caché, ya no solo existe en tus servidores. En su lugar, pueden existir en fragmentos dentro de las memorias caché de los navegadores de tus usuarios finales.
En general, la mayoría de las guías sobre el almacenamiento en caché hablarán sobre este tipo de configuración: si quieres almacenar en caché durante una hora, varias horas, etcétera. Para configurar este tipo de caché, usa un encabezado como este (que almacena en caché durante 3,600 segundos o una hora):
Cache-Control: max-age=3600,immutable,public
Un último punto. Si creas contenido oportuno al que los usuarios suelen acceder solo una vez (como artículos de noticias), creo que nunca debería almacenarse en caché y que deberías usar la configuración predeterminada que se indica más arriba. Creo que a menudo sobreestimamos el valor del almacenamiento en caché en comparación con el deseo del usuario de ver siempre el contenido más reciente y mejor, como una actualización importante sobre una noticia o un evento actual.
Opciones que no son HTML
Además del HTML, estas son algunas otras opciones para archivos que se encuentran en el término medio:
En general, busca recursos que no afecten a otros
- Por ejemplo, evita CSS, ya que provoca cambios en la forma en que se renderiza el HTML.
Imágenes grandes que se usan como parte de artículos oportunos
- Es probable que tus usuarios no visiten un artículo más de unas pocas veces, por lo que no debes almacenar en caché las fotos ni las imágenes hero para siempre y desperdiciar el almacenamiento.
Es un recurso que representa algo que tiene una vida útil.
- Es posible que los datos JSON sobre el clima solo se publiquen cada hora, por lo que puedes almacenar en caché el resultado anterior durante una hora; no cambiará en tu ventana.
- Las compilaciones de un proyecto de código abierto pueden tener un límite de frecuencia, por lo que debes almacenar en caché una imagen de estado de compilación hasta que sea posible que el estado cambie.
Resumen
Cuando los usuarios cargan tu sitio por segunda vez, ya tienes un voto de confianza: quieren volver y obtener más de lo que ofreces. En este punto, no siempre se trata solo de reducir ese tiempo de carga, y tienes muchas opciones disponibles para asegurarte de que tu navegador solo haga el trabajo que necesita para ofrecer una experiencia rápida y actualizada.
El almacenamiento en caché no es un concepto nuevo en la Web, pero tal vez necesite un valor predeterminado razonable: considera usar uno y aceptar mejores estrategias de almacenamiento en caché cuando las necesites. ¡Gracias por leer esta información!
Consulta también
Para obtener una guía general sobre la caché HTTP, consulta Evita solicitudes de red innecesarias con la caché HTTP.