1. Introduction

Browser cache is a browser that stores the static resources (HTML, CSS, JS) requested by the user to the local disk of the computer. When the browser accesses it again, it can be directly loaded from the local disk, and there is no need to go to the server to request.

This is not to say that caching is without its drawbacks. If not handled properly, the server code can be updated, but the user can still have the same page. Therefore, the front-end should make a reasonable caching strategy according to the actual situation of each resource in the project.

Advantages of caching:

  • It reduces redundant data transmission and saves network costs
  • Reduce server burden, improve website performance
  • Speed up the client loading page speed

2. Cache process

Here is an overview of the process of caching resources in the browser.

If you think about it, the browser has a database of caching rules, or a mapping table, that maps the cache resource information to the location of the actual file on the computer disk. (Don’t take it seriously)

The table of caching rules is visible in the browser: Chrome ://cache/

//net-internals/#httpCache ://net-internals/#httpCache ://net-internals/#httpCache

The first time a browser requests a resource

The above mentioned caching rule is to declare the requested resource, which caching policy to adopt? How long does the cache last? Wait… This rule, on the other hand, is returned in the HTTP header.

Note: Response header, not Request header!!

And in fact, the request header also carries rule information, so as we’ll see, we need to distinguish between request and Response

3. Cache rules

Strong cache and negotiated cache.

Strong cache

If the resource is not expired, the cache is fetched. If it is expired, the server is requested.

How do you determine if a resource is expired? In other words, what about the rules for strong caching?

It mainly depends on the value of cache-control in Response headers, and the max-age in the figure is 31XXXXxxx, which means that in these seconds, the Cache is directly used, and the request to the server will continue if the value exceeds

Next to cache-control, there’s an Expires Expires, which is pretty much obsolete, so don’t worry

Meanings of the values of cache-control:

Private: Only the browser can cache

Public: Both browsers and proxy servers can cache (for private and public, the front end can consider the same, no further details)

Max -age= XXX expiration time (important)

No-cache Does not use strong cache (important)

No-store: No strong cache, no negotiated cache, almost no, the more cache the better

Note: You can have more than one rule at a time

Therefore, for strong Cache, we mainly study max-age and no-cache in cache-control

Therefore, to determine whether the resource hits the strong Cache, look at the value of cache-control in response. If max-age= XXX seconds, the resource hits the strong Cache. If the value of cache-control is no-cache, the negotiation Cache is used.

Strong cache process:

So the strong cache steps are clear:

  1. The first time to request a.js, the cache table does not contain the information, directly request the back-end server.
  2. The back-end server returns a.js, and the cache-control in the HTTP response header is max-age= XXXX, so it is a strong cache rule and stored in the cache table.
  3. The second request for A.js is max-age in the cache table, so the strong cache is hit, and then determine whether it is expired. If it is not expired, it directly reads the a.JS in the cache. If it is expired, the step of negotiating the cache is performed.

Pay attention to

Max -age=0; no-cache =0; max-age=0; no-cache =0; max-age=0; Although it actually looks the same.

www.itranslater.com/qa/details/…

Negotiate the cache

Trigger condition:

  1. The value of cache-control is no-cache.
  2. Or Max -age expired (strong cache, but it always expires)

That is, you might end up negotiating a cache anyway (except for no-store)

This graph, although strong cache hits, also has ETag and last-Modified, which are the rules for negotiated caches. Although the previous strong caching process was not related to them…

ETag: one for each file. When a file is changed, it changes. It can look like MD5

Last-modified: Indicates the time when the file was Modified

In other words, each time the RESPONSE header is returned with ETag and last-modified, the request header will be returned with ETag and last-modified (but with the name changed to ETag–> if-none-match, Last-modified –> if-modified-since), the server compares the identifier you brought to the resource, the current identifier of the resource, and determines If the resource has changed.

This process is circular, meaning that the cache table updates the rules after each successful request.

1. When the NTH request succeeds:

2. Update the ETag value of the resource in the cache table

3. The n+1 request:

ETag — > if-none-match ETag — > if-none-match ETag — > if-none-match

Graph:

So negotiate the cache step summary:

  1. When a user requests a resource, the user sends the local ETag of the resource to the server at the same time, and the server compares it with the latest resource.
  2. If the resource has not changed, 304 is returned and the browser reads from the local cache.
  3. If the resource has changed, return 200, returning the latest resource.

4. Cache hits are displayed

  1. Get new resources from the server

  1. A strong cache is hit and the resource is not expired. Read the local cache directly

  1. The negotiation cache is matched and the resource is not changed. The local cache is read

Note: The negotiation cache always sends a request to the server. However, if the resource is not changed, only the header information is returned, so the size is small. When the resource changes, the body data is returned, so the size will be large.

7. Other

0. How do I configure a resource cache rule

You can either have a back-end server configuration, or you can configure it in Nginx. You will update an Nginx configuration later

1. Why Etag

You might think that last-Modified is enough to let the browser know if the local cached copy is new enough, so why need an Etag? The introduction of ETAGS in HTTP1.1 (that is, the addition of ETags to address the previous if-modified shortcoming) was designed to address several last-modified issues:

  • Some files may change periodically, but the contents of the file are not changed (only the modification time is changed). At this time, we do not want the client to think that the file has been changed and GET again.

  • Some files are Modified very frequently, such as in seconds or less (for example, N changes in 1s), and if-modified-since can be checked at a granularity of S, which is impossible to determine (or the UNIX record MTIME is accurate only to seconds).

  • Some servers do not have the exact last modification time of a file.

2. The difference between strong cache and negotiated cache can be expressed in the following table:

3. Impact of user behavior on cache

That is, F5 will skip the strong cache rule and go directly to the negotiated cache; Ctrl+F5, skip all caching rules, and retrieve the resource just like the first request

4. Project cache policy

For example, in the vue project, the scaffold has already hash the changed files, so we do not need to operate the general JS and CSS files.

For index.html, we need to do no-store processing on nginx, that is, do not cache index.html at all, and request the latest HTML every time… Because HTML will link CSS and JS, if MY HTML is still cached, then the link is still old CSS, think about it??

6. Summary

Borrow two figures