Las cabeceras de cache del protocolo HTTP

Publicado por pico.dev el , actualizado el .
blog-stack planeta-codigo planeta-linux software software-libre
Comentarios

Establecer directivas de cacheo en los recursos devueltos en una página o aplicación web tiene las ventajas de reducir el número de peticiones que llegan al servidor mejorando la latencia y el rendimiento pudiendo atender a más usuarios y mejora los tiempos de carga de las páginas. Usando varias directivas de cacheo la aplicación es capaz de determinar cómo quiere que el contenido devuelto o los recursos sean cacheados por los clientes o servidores de cache intermedios.

HTML

Cachear aquella información que es costosa de generar y es muy solicitada consigue por un lado evitar que el servidor sea capaz de atender todo el tráfico reduciendo la cantidad de capacidad necesaria del servidor y por otro lado consigue que la información sea devuelta en menor tiempo. Para aquella información que no necesite estar completamente actualizada o que no cambia cada poco tiempo es candidata a cachearla en caso necesario. La cache se puede realizar en los navegadores guardando estos recursos como imágenes y hojas de estilos que consiguen reducir el número de peticiones al servidor y mostrando la página más rápidamente al usuario. La cache también se puede hacer en el lado del servidor usando soluciones específicas como Varnish, memcached o para los casos más habituales que serán la mayoría las funcionalidades incorporadas en el servidor web como en el caso de Nginx.

El cacheo o almacenamiento temporal de datos puede hacerse a diferentes niveles sin ser exclusivos y de diferentes tipos de información. En la base de datos, en la aplicación, a nivel de página, con servidor intermedio o en el cliente.

Según la cantidad de tiempo de expiración que establezcamos como cache para el contenido conseguiremos variar el número de aciertos en la cache, aumentando el tiempo unos pocos segundos el tiempo que almacenamos en la cache el contenido conseguimos aumentar el porcentaje de aciertos en mayor medida. Con un tiempo de cache de un minuto ya se consiguen porcentajes elevados de aciertos según el número de peticiones realizadas en ese periodo de tiempo.

Petición con acierto y fallo en la cache

En el protocolo HTTP 1.1 se definieron tres mecanismos para las caches:

  • Validez: permite usar un recurso sin hacer ninguna comprobación con el servidor ni para revalidarlo. Por ejemplo, la cabecera Expires indica en que momento el recurso puede haberse quedado obsoleto y se debería revalidar. La cabecera Cache-Control: max-age indica durante cuanto tiempo el recurso puede considerarse válido. Esto evita hacer peticiones al servidor si los recursos se consideran válidos.
  • Validación: una vez que un recurso se considera que puede ser obsoleto se debería comprobar haciendo una petición al servidor para conocer si sigue siendo válido y si no lo es obtener una nueva versión. Usando las cabeceras If-Modified-Since o Etag puede comprobarse si el recurso ha sido modificado con posterioridad a una fecha o ha variado. Se ha de hacer una petición para comprobar la validez del recurso pero los casos que sigan siendo válidos no hará falta descargarlos de nuevo. Si el recurso sigue siendo válido el servidor responde con el código de estado 304 y sin el contenido en la respuesta.
  • Invalidación: las peticiones que usen los métodos PUT, POST y DELETE pueden invalidar recursos ya que modifican el estado del servidor.

El servidor especifica como quiere que el contenido o recursos que devuelve sean cacheados a través de varias directivas del protocolo HTTP, establecidas como cabeceras en la respuesta cuando se solicita el contenido o recurso. Algunas cabeceras realizan funciones similares habiendo cierto solapamiento de funcionalidad. Son las siguientes:

  • Cache-Control: private | public, no-cache, no-store, max-age, s-maxage, must-revalidate, no-transform, proxy-revalidate
    • El valor private indica que el recurso es privado para el usuario y no debería ser cacheado. Esto no hace el recurso más seguro ya que la información no se transmite cifrada para ello hay que usar un protocolo seguro con TLS/SSL.
    • no-cache el recurso no debería ser cacheado.
    • no-store el recurso no debería ser almacenado.
    • max-age normalmente se ha usado la directiva Expires pero esta permite establecer el máximo tiempo especificado en segundos a cachear un recurso.
    • s-maxage similar a max-age pero para las caches intermedias entre el cliente y el servidor.
    • must-revalidate cuando un recurso se queda obsoleto no se debe usar sin antes validar contra el servidor si sigue siendo válido.
    • no-transform indica que el contenido original no debe ser modificado, por ejemplo, modificando el recurso para optimizarlo si por ejemplo se trata de una imagen.
    • proxy-revalidate lo mismo que must-revalidate pero para las caches intermedias.
  • If-Modified-Since: si el recurso solicitado con su variante no ha sido modificado con posterioridad a una fecha se devolverá un código de estado 304 sin el contenido.
  • Expires: es una marca de tiempo que indica cuando el recurso expira, dado que se basa en el tiempo no es muy precisa ya que los relojes de cada ordenador no están perfectamente sincronizados y hay variaciones incluso de minutos. Preferiblemente es mejor usar Etag o max-age.
  • Etag: entity-tag o etag es un código hash único del contenido que permite conocer si el recurso ha cambiado. Si el recurso no ha cambiado no hace falta devolver el recurso, si ha cambiado se devuelve en la misma petición. Al no depender de una marca de tiempo como Expires o max-age es más fiable.
  • Vary: indica que el recurso varía según alguna cabecera proporcionada por el cliente como por ejemplo User-Agent o Accept-Encoding.
  • Pragma: esta es una directiva antigua que indicada como pragma: no-cache, se interpreta como cache-control: no-cache.