In our daily work, after the front-end code is packaged, static resources need to be generated and released to the static server, and some operation and maintenance configuration of static resources are done, among which gZIP and cache Settings are essential. These two are the most direct impact on site performance and user experience.

Advantages of caching:

  • Reduces unnecessary data transmission and saves bandwidth
  • Reduce server load and improve site performance
  • Accelerated client loading web page speed
  • User experience friendly
  • .

Disadvantages:

  • If the resource is modified, but the client does not update in time, causing users to obtain the information of the old version, the situation is very bad.

Therefore, in order to avoid the error of setting cache, it is very important to master the principle of cache for our work to configure cache more reasonably.

Strong cache

What exactly is strong caching? Strong means mandatory. When the browser requests a file, the server sets the time in the respone header. If it tells the client that the time is not expired, the server does not need to re-request the server for the next request. So strong caching requires server-side configuration. The cache duration and cache type are controlled by the server: cache-control of respone Header. The common Settings are max-age public private no-cache no-store

The diagram below, set the cahe – control: Max – age = 31536000, public, immutable

image.png

Max-age indicates that the cache time is 31536000 seconds (one year). Public indicates that the cache can be used by browsers and proxy servers. Proxy servers are usually used by Nginx. Immutable means that a resource is never mutable, but it is not. It is set to immutable so that users do not call the server when refreshing the page! What you mean? That is, if you only set cahe-control:max-age=31536000,public this is a strong cache. Every time the user opens the page normally, the browser will determine whether the cache has expired, and if it has not, it will read the data from the cache. But there are some “smart” users will click on the top left corner of the browser refresh button to refresh the page, then even if the resource has not expired never so fast (1), the browser will go directly to request to the server, this is the request of the additional cost, then go quite so the negotiation process of cache (as below). If cahe-control:max-age=315360000,public = immutable, the browser does not request service even if the user updates the page, the browser reads the cache directly from the local disk or memory and returns 200 status. See the red box above (from Memory Cache). This is what the Facebook team suggested to the IETF working group that developed the HTTP standard in 2015: They wanted HTTP to add a property field to the cache-Control response header to indicate that the resource would never expire, so that browsers would no longer have to make conditional requests for those resources.

Strong cache summary

  1. Cache-control: max-age= XXXX, public client and proxy server can cache this resource. If the client has a request for the resource within XXX seconds, it directly reads the cache,statu code:200, and sends an HTTP request to the server if the user refreshes the resource

  2. Cache-control: max-age= XXXX, private allows only the client to cache the resource. The proxy server does not cache the client directly reads the cache in XXX seconds,statu code:200

  3. Cache-control: max-age= XXXX, immutable The client reads the cache directly if it has requests for this resource within XXX seconds. Statu code:200 Does not send HTTP requests to the server even after the user flusher the cache

  4. Cache-control: no-cache Skips setting strong cache, but does not prevent setting negotiated cache; If you have a strong cache, you will only use the negotiation cache if the strong cache fails. If you set no-cache, you will not use the negotiation cache.

  5. Cache-control: no-store cache. This will cause the client and server to not cache, so there is no so-called strong cache, negotiation cache.

Negotiation cache

The above mentioned strong caching is to set an expiration time for the resource. Each time the client requests the resource, it will check whether the expiration time is correct. The server is only asked if it has expired. So, strong caching is meant to be self-sustaining for clients. However, when the client requests the resource and finds that it is expired, it will request the server, and then the process of requesting the server can set up the negotiation cache. In this case, the negotiation cache requires interaction between the client and the server.

How do I set negotiated cache?

Settings in the Response header

etag: '5c20abbd-e2e8'
last-modified: Mon, 24 Dec 2018 09:49:49 GMT
Copy the code

Etag: each file has a hash, which is unique to each file, just like when webpack is used, each resource will have this thing, for example, app.js will become app.c20abbde.js after package, add a unique hash, also to solve the cache problem.

Last-modified: Indicates the modification time of a file, accurate to the second

That is, eTag and Last-Modified from the Response header are returned with each request, and the next request is put in the Request header. The server compares the tag that you brought with it to determine if the resource has changed. If it changes, it returns the new resource directly and updates the etag and last-Modified labels of the corresponding Response header. If the resource has not been modified, then the eTAG, last-modified, and last-modified cache will be negotiated for each request from the client.

Send a request -> see if the resource is expired -> Expired -> Request server -> server comparison resource is really expired -> Not expired -> Return 304 status code -> client with the cache of the old resource.

This is a complete cache negotiation process.

Of course, when the server discovers that the resource is truly expired, it does the following:

Send a request -> See if the resource is expired -> Expired -> Request server -> Server compare whether the resource is really expired -> Expired -> Return 200 status code -> If the client receives the resource for the first time, Write down max-age, etag, last-Modified, and so on in its cache-control.

Therefore, the negotiation cache steps are summarized as follows:

When requesting a resource, the local ETAG of the resource is sent to the server for comparison with the latest resource. If the resource has not changed, 304 is returned and the browser reads the local cache. If the resource has changed, return 200 to return the latest resource.

In addition, etag and Last-Modified in the response header will change the key name in the request header when the client initiates a request to the server again:

// response header etag: '5c20abbd-e2e8' last-modified: Mon, 24 Dec 2018 09:49:49 GMT // Request header changed to if-none-matched: '5C20ABBD-e2E8' if-modified since: Mon, 24 Dec 2018 09:49:49 GMTCopy the code

Why eTag? You might think that using Last-Modified is enough to let the browser know if the local cached copy is new enough, so why etag? The introduction of eTag in HTTP1.1 (that is, eTAG was added to address the previous if-Modified defect) was primarily intended to address several difficult last-Modified problems:

  1. Some files may change periodically, but their contents do not change (just change the modification time). At this point we do not want the client to think that the file has been modified and get again;

  2. Some files are modified very frequently, such as if they are modified in seconds or less (say N times in 1s), and if-modified-since the granularity that can be checked is in seconds, so the modification cannot be determined (or the UNIX record MTIME is only accurate to seconds).

  3. Some servers do not know exactly when a file was last modified.

How to set strong cache and negotiation cache

  1. Back-end server such as nodejs: res.setheader (‘max-age’: ‘3600 public’) res.setheader (etag: ‘5c20abbd-e2e8’) res.setHeader(‘last-modified’: Mon, 24 Dec 2018 09:49:49 GMT)

  2. Nginx configuration

    image.png

If you know what you’re doing, you won’t be in a hurry.

How to use it?

For example, a single page file generated by vue-CLI packaging has an HTML and a bunch of JS, CSS and IMG resources. How to set up these files? What are the core requirements

  1. Have a cache, of course

  2. When sending a new package, avoid loading old cache resources

    Packed static files

Advice: The index. HTML file is cached by negotiation. The reason is that the user should request the server directly instead of the browser cache each time he requests the index. Be sure **** do not set strong cache!!

Other resources adopt strong cache + negotiated cache;

Reference article: juejin.cn/post/684490… www.cnblogs.com/ziyunfei/p/…

www.jianshu.com/p/9c95db596…