This is the 49th original article without water. For more original articles, please follow us by scanning the QR code at 👆. This article was first published on the blog of the front end team of The Political Cloud: Illustrated HTTP cache

preface

HTTP caching is one of the most important things a front-end engineer needs to know. This article will make a detailed explanation of the whole process of HTTP caching, and strive to make sure that after reading the whole article, you have an overall understanding of caching.

HTTP caching is divided into two types, one is strong caching and the other is negotiated caching. It speeds up resource acquisition, improves user experience, reduces network transmission, and relieves pressure on the server. Here’s an overview of how caching works:

Strong cache

No need to send a request to the server, directly read the browser’s local cache, in Chrome Network display HTTP status code 200, in Chrome, Strong caches are divided into Disk Cache and Memory Cache. The location of the Cache is controlled by the browser. Strong caching is controlled by a combination of the Header attributes Expires, cache-Control, and Pragma.

A. Expires

The Expires value is an HTTP date, and when the browser makes a request, it compares the system time to the Expires value. If the system time exceeds the Expires value, the cache Expires. If the system time is inconsistent with the server time, the cache validity period may be incorrect. Expires has the lowest priority of the three Header attributes.

cache-control

Cache-control is an HTTP/1.1 attribute that can be used in both request headers and response headers.

  • Max-age: the unit is second. The cache time is calculated in seconds from the time when the cache is initiated. If the interval exceeds the number of seconds, the cache is invalid
  • No-cache: no strong cache is used. Check whether the cache is fresh with the server
  • No-store: disables the use of cache (including negotiated cache) and requests the latest resources from the server each time
  • Private: Caches dedicated to individuals. Intermediate proxies, CDNS, and others cannot cache this response
  • Public: The response can be cached by the intermediate proxy, CDN, etc
  • Must -revalidate: This parameter is valid before the cache expires, after which it must be verified with the server

A. Pragma

Pragma has only one attribute value, no-cache, which has the same effect as no-cache in cache-Control. It does not use strong cache, and needs to check whether the cache is fresh with the server. It has the highest priority among the three header attributes.

To verify the three properties of a strong cache, use a service called Express:

const express = require('express');
const app = express();
var options = { 
  etag: false.// Disable negotiation cache
  lastModified: false.// Disable negotiation cache
  setHeaders: (res, path, stat) = > {
    res.set('Cache-Control'.'max-age=10'); // Strong cache timeout is 10 seconds}}; app.use(express.static((__dirname +'/public'), options));
app.listen(3000);
Copy the code

The first time it loads, the page requests data from the server and adds cache-control to the Response Header with an expiration time of 10 seconds.

On the second load, the Date header property is not updated, and you can see that the browser is using the strong cache directly, and actually does not send the request.

After the 10-second timeout, request the resource again:

When Pragma and cache-control exist together, Pragma takes precedence over cache-Control.

Negotiate the cache

If-modified-since or if-none-match is set in the request header when the browser’s strong cache is invalid. If the request header is set to if-modified-since or if-none-match, the server verifies whether the negotiated cache is hit. If the negotiated cache is hit, the server verifies whether the negotiated cache is hit. The 304 status is returned, the browser cache is loaded, and the response header is set to last-Modified or ETag.

ETag/If – None – Match

The value of ETag/ if-none-match is a string of hash codes representing the identifier of a resource. When the server file changes, its hash code changes. The if-none-match in the request header is compared with the hash value of the current file. If they are equal, the negotiated cache is hit. If the hash code starts with “W/”, the negotiated cache check is weak. Resources are requested only when the file difference on the server (determined by the ETag calculation method) is enough to trigger a change in the hash suffix. Otherwise return 304 and load the browser cache.

A. last-modified/If – Modified – Since

The last-modified/if-modified-since value represents the Last modification time of the file. The server will put the Last modification time of the resource in the last-Modified response header for the first request. The request header takes the last-modified time of the Last response header and places it in the if-Modified-since request header property. The server compares the Last modification time of the file with the value of if-Modified-since. If the value is equal, 304 is returned. And load the browser cache.

To verify the negotiated cache, use a service called Express:

const express = require('express');
const app = express();
var options = { 
  etag: true.// Enable negotiation cache
  lastModified: true.// Enable negotiation cache
  setHeaders: (res, path, stat) = > {
    res.set({
      'Cache-Control': 'max-age=00'.// Browsers do not cache strongly
      'Pragma': 'no-cache'.// Browsers do not cache strongly}); }}; app.use(express.static((__dirname +'/public'), options));
app.listen(3001);
Copy the code

First request for resource:

On the second request for the resource, the server verifies whether the file has been Modified based on if-modified-since and if-none-match in the request header.

Let’s verify how ETag changes the hash value in the case of strong check, adding only one line of space. In the code, I use MD5 encryption to calculate the hash value of the file.

Note: For demonstration purposes, the actual calculation is not encrypted by MD5. By default, Apache automatically generates the ETag by setting the FileEtag INode Mtime Size in FileEtag. Users can customize the ETag generation method of the file.

In order to ensure that lastModified does not affect the cache, I removed the last-modified/if-modified-since request header.

const express = require('express');
const CryptoJS = require('crypto-js/crypto-js');
const fs = require('fs');
const app = express();
var options = { 
  etag: true.// Only by Etag
  lastModified: false.// Turn off another negotiation cache
  setHeaders: (res, path, stat) = > {
    const data = fs.readFileSync(path, 'utf-8'); // Read the file
    const hash = CryptoJS.MD5((JSON.stringify(data))); / / the MD5 encryption
    res.set({
      'Cache-Control': 'max-age=00'.// Browsers do not cache strongly
      'Pragma': 'no-cache'.// Browsers do not cache strongly
      'ETag': hash, // Manually set the Etag value to the MD5 encrypted hash value}); }}; app.use(express.static((__dirname +'/public'), options));
app.listen(4000); // Use a new port number, otherwise the negotiation cache validated above will always exist
Copy the code

The first and second requests are as follows:

Then I modified test.js, adding a space and then deleting a space to keep the file content unchanged, but the modification time of the file was changed, so I initiated the third request. Since I generated ETag through MD5 encryption of the file content, although the modification time was changed, the request still returned 304. Read the browser cache.

The emergence of ETag/ if-none-match mainly solved a problem that last-modified/if-modified-since could not solve:

  • Last-modified/if-modified-since mistakenly returns 304 If the file is Modified at a frequency below the second level
  • Last-modified/if-modified-since mistakenly returns 304 If the file has been Modified but nothing has changed, as illustrated in the example above

conclusion

In actual use scenarios, such as the official website of zhengcai Cloud. Static resources, such as images and infrequently changing JS, use caching to speed up page loading. For example, the top navigation bar of the home page of zhengzhengyun, embedded SDK and so on.

At the end of this article, we will return to this flowchart, which covers the overall flow of HTTP caching. Once you are familiar with the overall flow, you can also use Node to verify HTTP caching yourself.

Recommended reading

Probably the most complete collection of text overflow truncation ellipsis schemes

An illustrated guide to unlock the mysteries of single sign-on

, recruiting

ZooTeam, a young passionate and creative front-end team, belongs to the PRODUCT R&D department of ZooTeam, based in picturesque Hangzhou. The team now has more than 50 front-end partners, with an average age of 27, and nearly 30% of them are full-stack engineers, no problem in the youth storm group. The members consist of “old” soldiers from Alibaba and netease, as well as fresh graduates from Zhejiang University, University of Science and Technology of China, Hangzhou Electric And other universities. In addition to daily business docking, the team also carried out technical exploration and practice in material system, engineering platform, building platform, performance experience, cloud application, data analysis and visualization, promoted and implemented a series of internal technical products, and continued to explore the new boundary of front-end technology system.

If you want to change what’s been bothering you, you want to start bothering you. If you want to change, you’ve been told you need more ideas, but you don’t have a solution. If you want change, you have the power to make it happen, but you don’t need it. If you want to change what you want to accomplish, you need a team to support you, but you don’t have the position to lead people. If you want to change the pace, it will be “5 years and 3 years of experience”; If you want to change the original savvy is good, but there is always a layer of fuzzy window… If you believe in the power of believing, believing that ordinary people can achieve extraordinary things, believing that you can meet a better version of yourself. If you want to be a part of the process of growing a front end team with deep business understanding, sound technology systems, technology value creation, and impact spillover as your business takes off, I think we should talk. Any time, waiting for you to write something and send it to [email protected]