Caching is a way to improve Web performance. By reusing previously acquired resources, caching relieves the pressure on the server and reduces the time for the client to obtain resources.

There are many types of caches, which can be broadly divided into two categories:

  • Shared cache: it stores responses that can be used by multiple users, such as proxy cache;
  • Private cache: can only be used by individual users, such as browser cache;

This article focuses on browser and proxy caches (which only cache GET responses), as well as gateway caches, CDN, reverse proxy caches, and load balancers deployed on servers to provide better stability, performance, and scalability for sites and Web applications.

1. Cache location:

  1. Service Worker: A separate thread that runs behind the browser and is typically used for caching. To use a Service Worker, you must use HTTPS as the transport protocol;
  2. Memory Cache: The Cache in Memory, which contains resources that have been obtained on the current page, such as styles, scripts, and images that have been downloaded on the page. Fast reads, but once the TAB page is closed, the cache in memory is released;
  3. Disk Cache: The Cache on a hard Disk. It is slow to read but has a larger capacity than the memory Cache and can be stored for a long time.
  4. Push Cache: A Cache that is actively pushed by the server to the client using HTTP /2. It is used only when the preceding three caches fail to be hit. It only exists in the session and is released once the session ends. It also has a very short cache time (about 5 minutes in Chrome) and does not strictly implement HTTP header caching instructions.

When the browser reads the cache, it checks for any of the caches in turn, and resends the request if none is hit.

Two, HTTP cache system:

The HTTP cache architecture is divided into three parts:

  • Cache storage policy: Used to determine whether HTTP response content can be cached to clients;
  • Cache expiration policy: used to determine whether the client can load data directly from the local cache and display it (or send a request to the server for it);
  • Cache comparison strategy: Used to compare the client cache and server resources to determine whether the client cache is still valid;

Strong cache and negotiated cache

Strong cache:

Also known as the local cache, the local cache holds the data to be requested and has not expired, so the browser does not send the actual HTTP request, but reads it directly from the local cache and returns a 200 status code. In Chrome, strong caches are divided into Disk Cache and Memory Cache. The location of the Cache is controlled by the browser. Whether to use strong caching (expiration) is controlled by the three header attributes Expires, cache-Control, and Pragma.

  • Expires is the HTTP /1.0 specification, and its value is an absolute time GMT-formatted time string. Example: Expires :Fri, 14 Apr 2017 10:47:02 GMT. This time represents the expiry time of the strong cache. However, this approach has an obvious disadvantage, because the time of failure is an absolute time, so when the server and client time deviation is large, it can lead to cache clutter. If cachA-Control :max-age= XXX and Expires are present at the same time, max-age takes higher precedence.

  • Cache-control is introduced in HTTP /1.1. It uses the max-age value of the field to determine whether the strong Cache is expired. It is a relative time. There are a few more common Settings:

    • no-cache: Forces the strong cache not to be matched, and directly determines whether to negotiate the cache with the server.
    • no-store: Disables the browser from caching data. Each time a user requests the resource, a request is sent to the server to obtain the complete resource data.
    • public: can be cached by all users, including end users and intermediate proxy servers such as CDN.
    • private: Can be cached only by the end user’s browser, not by intermediate cache servers such as CDN.
    • must-revalidate: Can be used before the cache expires, after the expiration must be verified to the server;
  • Pragma is a header attribute defined in the HTTP /1.0 standard. There is only one attribute value, no-cache, which has the same effect as no-cache in cache-Control, but the HTTP response header does not explicitly define this attribute. Therefore, it cannot be used as a complete replacement for the cache-control header defined in HTTP /1.1. Pragma is generally defined for backward compatibility with HTTP / 1.0-based clients.

Note: In the absence of any browser cache policy, the client calculates the time difference (in seconds) between two fields in the response header: Date and Last-Modified, and takes 10% of this value as the cache expiration period.

Negotiation cache:

Also called weak cache, if the strong cache is not hit (plain refresh or cache expiration), a spoofs request is sent to the server to verify that the negotiated cache is hit (whether the local cache is available). If the negotiated cache is hit, the response returns a 304 status code and displays a NotModified string. The negotiated cache uses two main sets of header attributes:

  • EtagandIf-None-Match(strong validator);
  • Last-ModifiedandIf-Modified-Since(weak validator);

The procedure for using the negotiated cache:

  1. On the first request, the server passes the header field the time when the resource was last modifiedLast-ModifiedSend to the client, along with a unique tagEtag, strong cache resources have these two attributes;
  2. If the strong cache is missed, the browser sends a request to the server:
    • The client passes the header fieldIf-None-MatchWill strongly cache resourcesEtagSend to the server;
    • The client also passes the header fieldIf-Modified-SinceWill strongly cache resourcesLast-ModifiedThe timestamp is sent to the server;
  3. The server will:
    • Check whether the Etag sent by the client is the same as the local Etag. If the Etag is different, resources are updated.
    • Check whether the resource is updated after the last-Modified timestamp;
    • If the resource is not updated, 304 status code is returned and negotiation cache is used. If the resource is not updated, 200 status code is returned and the server sends the updated resource to the client.

Etag has a higher priority than last-Modified

Why Etag:

  1. Some files may change periodically, but their contents do not change (only when they are modified), and at this point we want the client to think that the file has been modified and ask the server for complete data again.
  2. Some files are modified very frequently, such as in seconds or less,If-Modified-SinceThe granularity that can be checked is s-level, and this modification cannot be judged;
  3. Some servers don’t know exactly when a file was last modified;

Iv. Impact of user operations on cache:

  • When entering a URL in the address bar, jumping to a page link, opening a new window, and moving forward or backward in the history bar, the strong cache will be queried first, and then the negotiation cache will be queried.
  • Common refresh skips the strong cache and directly queries the negotiated cache.
  • The forced refresh skips the strong cache and negotiated cache and directly pulls resources from the server again.

References:

MDN HTTP cache HTTP cache and browser local storage Thoroughly understand the HTTP cache mechanism – three elements decomposition method based on caching strategy diagram HTTP cache