--- title: HTTP caching slug: Web/HTTP/Caching tags: - Caching - Guide - HTTP translation_of: Web/HTTP/Caching ---
El rendimiento de los sitios web y las aplicaciones puede mejorarse significativamente al reutilizar los recursos previamente obtenidos. Los cachés web reducen la latencia y el tráfico de red y, por lo tanto, reducen el tiempo necesario para mostrar una representación de un recurso. Al hacer uso del almacenamiento en caché HTTP, los sitios web se vuelven más sensible.
El almacenamiento en caché o Caching es una técnica que almacena una copia de un recurso dado y la devuelve cuando se solicita. Cuando un caché web tiene un recurso solicitado en su almacén, intercepta la solicitud y devuelve su copia en lugar de volver a descargarla desde el servidor de origen. Esto logra varios objetivos: facilita la carga del servidor que no necesita atender a todos los clientes, y mejora el rendimiento al estar más cerca del cliente, es decir, lleva menos tiempo transmitir el recurso de vuelta. Para un sitio web, es un componente importante para lograr un alto rendimiento. Por otro lado, debe configurarse correctamente, ya que no todos los recursos permanecen idénticos para siempre: es importante almacenar en caché un recurso solo hasta que cambie, no más.
Existen varios tipos de cachés: se pueden agrupar en dos categorías principales: cachés privados o compartidos. Un caché compartido es un caché que almacena respuestas para que más de un usuario las reutilice. Un caché privado está dedicado a un solo usuario. Esta página hablará principalmente sobre cachés de navegador y proxy, pero también hay cachés de puerta de enlace, CDN, cachés de proxy inverso y balanceadores de carga que se implementan en servidores web para una mejor confiabilidad, rendimiento y escala de sitios web y aplicaciones web.
Un caché privado está dedicado a un solo usuario. Es posible que ya hayas visto "almacenamiento en caché" en la configuración de tu navegador. Un caché de navegador contiene todos los documentos descargados a través de HTTP por el usuario. Este caché se usa para hacer que los documentos visitados estén disponibles para la navegación hacia atrás / adelante, guardar, ver como fuente, etc. sin requerir un viaje adicional al servidor. También mejora la navegación fuera de línea del contenido en caché.
Un caché compartido es un caché que almacena las respuestas para que sean reutilizado por más de un usuario. Por ejemplo, un ISP o su compañía podrían haber configurado un proxy web como parte de su infraestructura de red local para servir a muchos usuarios, de modo que los recursos populares se reutilicen varias veces, lo que reduce el tráfico y la latencia de la red.
El almacenamiento en caché de HTTP es opcional, pero la reutilización de un recurso almacenado en caché es generalmente deseable. Sin embargo, los cachés HTTP comunes generalmente se limitan al almacenamiento en caché de las respuestas a {{HTTPMethod ("GET")}} y pueden rechazar otros métodos. La clave de caché principal consiste en el método de solicitud y el URI de destino (muchas veces solo se usa el URL, ya que solo las solicitudes GET son destinos de almacenamiento en caché). Las entradas de caché más comunes son:
Una entrada de caché también puede consistir en múltiples respuestas almacenadas, diferenciadas por una clave secundaria, si la solicitud es causa de la negociación de contenido. Para obtener más detalles, consulta la información sobre el encabezado {{HTTPHeader ("Vary")}} más abajo.
Cache-control
El {{HTTPHeader("Cache-Control")}} HTTP/1.1 general-header campo se utiliza para indicar directivas para los mecanismos de caché tanto en solicitudes (requests) como en respuestas (response). Utiliza este encabezado para definir tus políticas de almacenamiento en caché con la variedad de directivas que proporciona.
El caché no debe almacenar nada sobre la solicitud del cliente o la respuesta del servidor. Se envía una solicitud al servidor y se descarga una respuesta completa cada vez.
Cache-Control: no-store Cache-Control: no-cache, no-store, must-revalidate
Un caché enviará la solicitud al servidor de origen para su validación antes de liberar una copia en caché.
Cache-Control: no-cache
La directiva "public" indica que la respuesta puede ser almacenada en caché por cualquier caché. Esto puede ser útil, si las páginas con autentificación HTTP o códigos de estado de respuesta que normalmente no se pueden almacenar en caché, ahora deben almacenarse en caché.
Por otro lado, la directiva "private" indica que la respuesta está dirigida a un solo usuario y no debe ser almacenada por un caché compartido. Un caché de navegador privado puede almacenar la respuesta en este caso.
Cache-Control: private Cache-Control: public
La directiva más importante aquí es "max-age=<seconds>
" que es la máxima cantidad de tiempo que un recurso será considerado nuevo. Contrariamente a {{HTTPHeader("Expires")}}, esta directiva es relativa al momento de la solicitud. Para los archivos de la aplicación que no cambiarán, generalmente se puede agregar almacenamiento en caché agresivo.Esto incluye archivos estáticos como imágenes, archivos CSS y archivos JavaScript, por ejemplo.
Para más detalles, ver la sección Actualización más abajo.
Cache-Control: max-age=31536000
Cuando se usa la directiva "must-revalidate
", la caché debe verificar el estado de los recursos obsoletos antes de usarlos, los caducados no deben usarse. Para más detalles vea la sección Validación.
Cache-Cit is not specified for HTTP responses and is therefore not a reliable replacement for the general HTTP/1.1Cache-Control
header, although it does behave the same asCache-Control: no-cache
, if theCache-Control
header field is omitted in a request. UsePragma
only for backwards compatibility with HTTP/1.0 clientsontrol: must-revalidate
Pragma
{{HTTPHeader("Pragma")}} es una cabecera HTTP/1.0, no se especifica para las respuestas HTTP y, por lo tanto, no es un reemplazo de confianza para el encabezado general de HTTP / 1.1 Cache-Control, aunque se comporta igual que Cache-Control: no-cache, si el campo del encabezado Cache-Control se omite en una solicitud. Utiliza Pragma solo para compatibilidad con versiones anteriores de clientes HTTP / 1.0
Una vez que un recurso se almacena en una caché, teóricamente podría ser servido por la caché para siempre. Las cachés tienen almacenamiento finito por lo que los elementos se eliminan periódicamente del almacenamiento. Este proceso se llama desalojo de caché. Por otro lado, algunos recursos pueden cambiar en el servidor, por lo que la memoria caché debe actualizarse. Como HTTP es un protocolo cliente-servidor, los servidores no pueden ponerse en contacto con cachés y clientes cuando cambia un recurso; tienen que comunicar un tiempo de caducidad para el recurso. Antes de este tiempo de expiración, el recurso está fresco; después de la fecha de caducidad, el recurso está obsoleto. Los algoritmos de desalojo a menudo privilegian recursos frescos sobre recursos obsoletos. Ten en cuenta que un recurso obsoleto no se desaloja ni se ignora; cuando la caché recibe una solicitud de un recurso obsoleto, reenvía esta solicitud con un {{HTTPHeader ("If-None-Match")}} para verificar si aún está fresco. Si es así, el servidor devuelve un encabezado {{HTTPStatus ("304")}} (No modificado) sin enviar el cuerpo del recurso solicitado, ahorrando algo de ancho de banda.
Aquí hay un ejemplo de este proceso con un proxy de caché compartido:
La vida útil de la frescura se calcula en base a varios encabezados. Si se especifica un encabezado "Cache-control: max-age=N
", entonces el tiempo de frescura es igual a N. Si este encabezado no está presente, que es el caso más frecuente, se verifica si hay un encabezado {{HTTPHeader("Expires")}} presente. Si existe un encabezado Expires
, entonces su valor menos el valor del encabezado {{HTTPHeader("Date")}} determina el tiempo de actualización. Finalmente si ninguno de los encabezados está presente, busca un encabezado {{HTTPHeader("Last-Modified")}}. Si este encabezado está presente, la vida útil de actualización es igual al valor del encabezado Date
menos el valor del encabezado Last-modified
dividido entre 10.
El tiempo de expiración se calcula de la siguiente manera:
tiempoExpiración = tiempoResponsive + tiempoActualización - tiempoActual
donde tiempoResponsive es el tiempo en que se recibió la respuesta según el navegador.
Cuanto más utilicemos los recursos en caché, mejor será la capacidad de respuesta y el rendimiento de un sitio web. Para optimizar esto, las buenas prácticas recomiendan establecer los tiempos de caducidad lo más lejos posible en el futuro. Esto es posible en los recursos que se actualizan regularmente o con frecuencia, pero es problemático para los recursos que rara vez se actualizan con poca frecuencia. Son los recursos que más se beneficiarían de los recursos de almacenamiento en caché, pero esto hace que sean muy difíciles de actualizar. Esto es típico de los recursos técnicos incluidos y vinculados desde cada página web: los archivos JavaScript y CSS cambian con poca frecuencia, pero cuando cambian, quieres que se actualicen rápidamente.
Los desarrolladores web crearon una técnica que Steve Souders llamó revving. Los archivos actualizados con poca frecuencia se nombran de forma específica: en su URL, generalmente en el nombre del archivo, se agrega un número de revisión (o versión). De esa manera, cada nueva revisión de ese recurso se considera como un recurso en sí mismo que nunca cambia y puede tener un tiempo de vencimiento muy lejano en el futuro, generalmente un año o incluso más. Para tener las nuevas versiones, se deben cambiar todos los enlaces a ellas, es el inconveniente de este método: complejidad adicional que generalmente es atendida por la cadena de herramientas utilizada por los desarrolladores web. Cuando los recursos variables cambian con poca frecuencia, inducen un cambio adicional a los recursos a menudo variables. Cuando se leen, también las nuevas versiones de las otras.
Esta técnica tiene un beneficio adicional: la actualización de dos recursos en caché al mismo tiempo no conducirá a la situación en la que la versión obsoleta de un recurso se usa en combinación con la nueva versión del otro. Esto es muy importante cuando los sitios web tienen hojas de estilo CSS o scripts JS que tienen dependencias mutuas, es decir, dependen entre sí porque se refieren a los mismos elementos HTML
La versión de revisión agregada a los recursos revisados no necesita ser una cadena de revisión clásica como 1.1.3, o incluso un conjunto de números en crecimiento monótono. Puede ser cualquier cosa que evite colisiones, como un hash o una fecha.
La revalidación se activa cuando el usuario presiona el botón de recargar. También se activa en la navegación normal si la respuesta en caché incluye el encabezado "Cache-control: must-revalidate
". Otro factor son las preferencias de validación de caché en el panel de preferencias Advanced->Cache
. Hay una opción para forzar una validación cada vez que se carga un documento.
Cuando se alcanza el tiempo de caducidad de un documento almacenado en caché, se valida o se recupera nuevamente. La validación solo puede ocurrir si el servidor proporcionó un validador fuerte o un validador débil.
El encabezado de respuesta {{HTTPHeader("ETag")}} es un valor de agente opaco al usuario que se puede usar como un validador fuerte. Esto significa que un agente de usuario HTTP, como el navegador, no sabe qué representa esta cadena y no puede predecir cual sería su valor. Si el encabezado de ETag fue parte de la respuesta para un recurso, el cliente puede emitir un {{HTTPHeader("If-None-Match")}} en el encabezado de futuras solicitudes, para validar el recurso almacenado en caché.
El encabezado de respuesta {{HTTPHeader("Last-Modified")}} puede ser usado como un validador débil. Se considera débil porque solo tiene resolución de un segundo. Si el encabezado Last-Modified
está presente en una respuesta, entonces el cliente puede emitir un encabezado de solicitud {{HTTPHeader("If-Modified-Since")}} para validar el documento almacenado en caché.
Cuando se realiza una solicitud de validación, el servidor puede ignorar la solicitud y la respuesta de validación con un {{HTTPStatus(200)}} OK
, o puede devolver {{HTTPStatus(304)}} Not Modified
(con el cuerpo vacío) para indicar al navegador que use su copia en caché. La última respuesta también puede incluir encabezados que actualizan el tiempo de caducidad del documento almacenado en caché.
El encabezado de respuesta {{HTTPHeader("Vary")}} determina cómo hacer coincidir los encabezados de solicitudes futuras para decidir si se puede usar una respuesta en caché en lugar se solicitar una nueva desde el servidor de origen.
Cuando una caché recibe una solicitud que puede ser satisfecha por una respuesta en caché que tiene un campo de encabezado Vary
, no debe usar esa respuesta a menos que todos los campos de encabezado dominados por el encabezado Vary
coincidan tanto en la solicitud original (en caché) como en la nueva solicitud.
Esto puede ser útil para servir contenido dinámicamente, por ejemplo. Cuando se utiliza el encabezado Vary: User-Agent
, los servidores de almacenamiento en caché deben considerar al agente de usuario al decidir si se debe servir la página desde la memoria caché. Si distribuye contenido diferente a los usuarios móviles, puede ayudarlo a evitar que una memoria caché sirva erróneamente una versión de escritorio de su sitio para sus usuarios móviles. Además puede ayudar a Google y a otros motores de búsqueda a descubrir la versión móvil de una página, y también puede decirles que no se pretende ningún encubrimiento.
Vary: User-Agent
Debido a que el valor del encabezado {{HTTPHeader("User-Agent")}} es diferente ("varía") para los clientes móviles y de escritorio, los cachés no se usarán para servir contenido móvil por error a los usuarios de escritorio o viceversa.