What is cache

A Cache, also called a Cache, is a place where temporary data is stored, and the data stored in the Cache pool is called a Cache. When users need to use this data, they first look for it in the cache, and if they find it, they use it directly. If you can’t find it, look for it in another data source.

Why use caching

The essence of caching is to trade space for time, temporarily storing data instead of reading the latest data from the data source. The benefits of this approach vary from scenario to scenario.

Here’s an example:

When we need to drink water, we will take out a glass of water, go to the tap to receive a cup of water to drink. You can think about why you drink from a cup rather than from the tap.

Drinking from a cup does have some inherent problems, such as the water in the cup tends to get cold, but the water coming out of the tap is at a constant temperature. It’s a bit comical to imagine colleagues queuing up to drink from the tap, and we’d rather accept the fact that the water in the glass will get cold.

Drinking from a cup has several advantages:

  • Drinking from a cup solves the problem of always having to find the tap because the cup can hold more water at once.

  • Drinking from a cup is less likely to spill and waste water.

  • Drinking from a cup is more elegant than drinking from the tap.

We regard the cup as a cache pool, and the water in the cup as a cache. We accept that the water in the cup will get cold, which is equivalent to sacrificing the real-time performance of the data. To rephrase these advantages, the advantages of using caching become the following:

  • Reduce the system pressure;

  • Saving resource consumption;

  • Optimize the user experience.

The role of HTTP caching

One of the characteristics of the Internet is that it is unstable, and many users suffer from slow Internet speeds.

In a scenario where a large number of users access the server, real-time computing of data is also prone to bottlenecks, resulting in service slowdowns. From the advantages of cache technology, it is suitable to solve the problem of unstable network service.

HTTP cache protocol

An agreement is a rule that is followed and used by both parties during communication. For example, how many times did client and server communicate with each other about the new model?

Client: big brother, the new neX release?

Server: old brother, haven’t hair, you remember, don’t old to ask me!

A week later…

Client: Big brother, here I am again. What’s the latest situation?

Server: Same as last time.

A month later…..

Client: Brother, it’s been a month, how’s it going? !

Servers: Available for sale!

In this example, the client follows a certain rule when communicating with the server. Let’s take a look.

  • Data part: the content of the model;

  • Part of the agreement: 1) Don’t keep asking me, 2) What’s new, 3) Same as last time.

These words said by the server, the client can understand and understand the meaning contained in these words, which is a communication agreement reached between the client and the server.

4.1 HTTP Headers

Before introducing the HTTP caching protocol, let’s take a look at the basics of HTTP headers. We are all familiar with HTTP/HTTPS data requests. There is a kind of information called “header information” in HTTP data requests.

Header information is the kind of information that is passed to the client in a request or to the server in response. Let’s look at the components of the HTTP protocol.

The composition of an HTTP request

Status line, request header, message body consists of three parts.

The composition of an HTTP response

Status line, response header, response body.

The request header and response header are what we call “header information” or “message headers”. So what does header information do?

4.2 request header

As shown in the figure:

4.3 response headers

As shown in the figure:

Cache-control, the caching protocol we’ll talk about today, is also controlled in the header.

4.4 Cache Protocol

In the first section, we introduced three advantages of using caching technology, which also have three advantages for network data exchange.

1) Reduce system pressure

Using HTTP caching technology can effectively reduce the pressure on the server side, the server does not need to calculate data in real time and return data.

2) Save resource consumption

The HTTP cache technology can effectively avoid repeated data transmission and reduce traffic consumption.

3) Optimize the user experience

Using HTTP caching technology, local caches can be loaded faster, reducing user wait time.

Before we talk about how the HTTP protocol implements caching, let’s talk about caching types. HTTP caches are generally divided into two types, private caches and shared caches.

4.4.1 Private Cache

The cache is stored in the local or independent account system of the device and only used by the current user. It can be used to reduce server stress, improve user experience, and even achieve offline browsing.

4.4.2 Shared Cache

Shared cache is the data cached in proxy servers or other intermediate servers. CDN is commonly used here. This cache can be accessed by multiple users to reduce traffic and delay.

For a network data exchange, local caches and shared caches can exist at the same time, and the HTTP protocol specifies how to control the use and update of these caches. In HTTP, the control cache has two types of fields: one is Pragma; The other is cache-control.

Pragma is a field defined in HTTP/1.0 that supports almost all existing browsers.

But cache-Control, a relic of a bygone era, is gradually replacing it. Cache-control is a protocol introduced from HTTP/1.1. Some front-end developers choose to add Pragma on top of cache-Control for downward compatibility, and in fact Android webViews support both Pragma and cache-Control.

When Pragma and cache-Control appear together, Pragma takes precedence over cache-Control and of course, that’s not the point today, but you can look it up for yourself.

Let’s take a look at the specific definition of the cache-control cache protocol. According to the HTTP protocol, the server informs the client of the cache mode through cache-control in the response header, and the client can also inform the server of its cache requirements through cache-control in the request header.

4.4.3 Cache-control in response headers

Cache-control in the response header usually has the following values:

  • Cache-control: public

  • Cache-control: private

  • Cache-control: no-cache

  • Cache-control: no-store

  • Cache-control: no-transform

  • Cache-control: must-revalidate

  • Cache-control: proxy-revalidate

  • Cache-Control: max-age=

  • Cache-control: s-maxage=

4.4.4 Cache-control in request headers

Cache-control in the request header usually has the following values:

  • Cache-Control: max-age=

  • Cache-Control: max-stale[=]

  • Cache-Control: min-fresh=

  • Cache-control: no-cache

  • Cache-control: no-store

  • Cache-control: no-transform

  • Cache-control: only-if-cached

The Mozilla Developer website describes these values in the following categories.

4.4.5 Cacheability control

public

Indicates that the response can be cached by any object (including the client that sent the request, the proxy server, and so on), even content that is not normally cacheable. (E.g. 1. The response does not have a Max-age directive or Expires header; 2. The request method corresponding to this response is POST.

private

Indicates that the response can only be cached by a single user and not as a shared cache (that is, the proxy server cannot cache it). The private cache can cache the response content, for example, the corresponding user’s local browser.

no-cache

The cache is forced to submit the request to the original server for validation (negotiated cache validation) before the cache copy is published.

no-store

The cache should not store anything about the client request or the server response, that is, no cache is used.

4.4.6 Cache validity control

max-age=

Sets the maximum period for which the cache is stored, after which the cache is considered expired in seconds. In contrast to Expires, time is the time relative to the request.

s-maxage=

Overrides max-age or Expires headers, but only for shared caches (such as individual agents) and private caches ignore them.

max-stale[=]

Indicates that the client is willing to accept an expired resource. An optional number of seconds can be set to indicate that the response cannot be out of date beyond that given time.

min-fresh=

Indicates that the client wants to get a response that will keep it up to date for a specified number of seconds.

stale-while-revalidate=

Indicates that the client is willing to accept stale responses while asynchronously checking for new ones in the background. The second value indicates how long the customer is willing to accept stale responses.

**stale-if-error= **

Indicates that the customer is willing to accept the stale response if the new check fails. The second value represents how long the customer is willing to accept stale responses after the initial expiration.

4.4.7 Verifying and reloading

must-revalidate

Once a resource expires (such as if it has exceeded max-age), the cache cannot respond to subsequent requests with the resource until it is successfully validated to the original server.

proxy-revalidate

It has the same effect as must-revalidate, but applies only to shared caches (such as proxies) and is ignored by private caches.

4.4.8 Other controls

no-transform

Resources may not be converted or converted. HTTP headers such as content-encoding, content-range, and Content-Type cannot be modified by the proxy. For example, an opaque proxy or something like Google’s Light Mode might convert image formats to save cache space or reduce traffic on slow links. The no-transform directive does not allow this.

only-if-cached

Indicates that the client accepts only cached responses and does not check with the original server for newer copies.

It can be seen from these descriptions and classification that the control dimensions of cacheability control + cache effectiveness control + other controls are not in conflict and can jointly realize the limitation of the implementation mode of cache.

In fact, cache-control does accept multiple values at the same time, and multiple instructions can be used together to control the cache. If multiple conflicting instruction values are used, the instruction is cached by priority.

For example, if the values of no-store and max-age instructions are delivered together, the terminal will cache only according to no-store.

4.4.9 Actual analysis of protocol work

Professional operation and maintenance personnel must know what these descriptions mean. However, as a client or front end, it may be difficult for us to understand the actual caching effect under different configuration values just by looking at these technical terms.

So in order to figure out what the value does to the actual cache. I use two computers, respectively set up a static resource server (source server), a proxy server, through the simulation of online server scene, to verify several common cache control modes. The installation of Nginx is relatively simple and will not be covered here.

Static Resource server (source server)

** Windows + Nginx, ** configuration as follows:

Proxy server

Windows + Nginx, configure as follows:

After the server is set up, we change the value of cache-control one by one to simulate several common cache control modes to help you understand these values and deepen your impression. In everyday use, cache-control is more often placed in the response header to control the cache behavior of browsing, so let’s verify that cache-Control is placed in the response header.

Scenario: Static resource server (source server) does not add any cache-control identifier to the response header. There is no added id, which corresponds to the public id.

Public is usually the default, and if we don’t add any cache-control headers to the response, the default processing logic for this response is cache-Control: public.

If the server returns a 302 or 307 redirection response, add cache-control: Public causes the browser to Cache the redirection response, but does not Cache it if cache-control is not added, and it may be handled differently by different network frameworks or browsers.

Public means that either the browser or the proxy server can cache resources returned by the static resource server (the source server). Use a browser to access the static resource server directly (without going through the proxy server).

First visit

On the first visit, the server returns the 200 state and sends static HTML back to the client. The server also has the ETag and Last-Modified fields, so let’s move on. At this point the client does several things:

  • The contents of static resources are cached;

  • ETag and Last-Modified are logged for this content.

Click the Browser refresh button

After clicking the browser refresh button, the client browser requests the server again with the ETag and Last-Modified returned from the first request. The server uses these two parameters to assume that the client has cached the resource and the server does not need to return the resource again. So the server returns 304.

What happens if a proxy server is involved? Remember when we configured the proxy server, we set the proxy cache time for the proxy service to 10 seconds.

First visit

Click the Browser refresh button

When the browser’s refresh button is clicked, the client browser requests the server again with the ETag and Last-Modified returned from the first request. With these two parameters, the server thinks that the client has cached the resource and the server does not need to return the resource again, so the server returns 304.

Ngiux-cache-status HIT indicates that the proxy server has HIT the cache. The proxy server determines the validity of the client cache.

The third refresh 10 seconds later

As mentioned earlier, the proxy server cache validity period is set to 10 seconds. On the third refresh, the server still returns 304 and the resource does not need to be updated.

If ngiux-cache-status is EXPIRED, the proxy server will pass the request to the static resource server (the source server). If ngiux-cache-status is EXPIRED, the proxy server will pass the request to the static resource server. Validation of the cache done by the static resource server (source server).

During this process, the proxy server updates its cache again, resulting in the following fourth time.

Fourth refresh

The logical diagram is as follows;

With these four requests, we can clearly see the whole logic, and the proxy server directly replaces the static resource server (source server) in some cases. Because the public directive tells the proxy server that it can cache the data, the proxy server caches the data as configured for 10 seconds, after which it re-forwards the request to the static resource server (the source server) and re-caches it.

The proxy server has a time limit on the cache and will not re-request the static resource server (source server) until the time limit is reached. This reduces the pressure on the static resource server (source server). So why does the browser keep requesting the proxy server in the example above?

It should be noted that in this case, we were actually hitting the browser refresh button, which means that the client browser rerequests the server to validate the cached content.

** Max-age = 0 ** Max-age = 0 ** Max-age = 0 ** Max-age = 0 If you try to copy the URL to a new window in your browser and hit Enter to open the URL, instead of hitting the refresh button, it will look something like this.

Status Code: 200 OK (from disk cache) indicates that the response data is retrieved from the disk cache.

In android WebView, normally there is no refresh button (unless the developer writes one himself), so the WebView will not request the network, and it will fetch data from the disk cache every time, so the network request will not be seen during packet capture.

Now that you know the logic, let’s look at the description provided by Mozilla and see if we can get an idea of what’s going on.

4.4.10 Cacheability control in response headers

public

Indicates that the response can be cached by any object (including the client that sent the request, the proxy server, and so on), even content that is not normally cacheable. (E.g. 1. The response does not have a Max-age directive or Expires header; 2. The request method corresponding to this response is POST. This is actually the scenario we just verified.

private

Indicates that the response can only be cached by a single user and not as a shared cache (that is, the proxy server cannot cache it). The private cache can cache the response content, for example, the corresponding user’s local browser.

If you use private, it means that the resource can be cached by private users, and the cache will not be shared. In practice, when marked private, the browser can cache the resource, but the proxy server will not cache the resource. Private can be used to specify the user_id of the cache. This is a complex configuration.

no-cache

Force the cache to submit the request to the original server for validation (negotiated cache validation).

This directive is often used by the server and is easily confused with the no-store directive. Many front-end and client students believe that when the server response is marked with no-cache, then the client will not cache, and will request the server to fetch new content every time. It’s only half right.

In this scenario, the browser does request the server every time, but that doesn’t mean the browser doesn’t cache the resource. Mozilla’s official explanation is “submit the request to the original server for validation.” If the cache is fine, the server will return 304 and let the browser continue to use its local cache.

no-store

Nothing about client requests or server responses should be stored, that is, no caching is used.

This instruction does not use the local cache at all. In this mode, the client does not record any caches, including Etag, etc., and reinitiates the request each time with 200 responses and corresponding data. If the front-end wants its web pages not cached at all, try this directive.

Order to solve the above client, and the proxy server can cache problem, some students will have the question, if let the client to the local cache, so if you do not normally go to manually refresh, the client will not request to the server, after sending the new front end, the client how to choose the suitable time to request to the server?

This is where cache validity control comes in. The cache validation between the browser and the server is mutual, meaning that the server can tell the browser how long you can use the cache and how long you can keep it.

Let’s take a look at how the server tells the client how long the cache will last. Cache validity control directives are typically sent to clients together with cacheability directives.

We added the max-age attribute to the header of the server, and to prevent the proxy server from invalying the proxy cache in advance, we set the proxy server’s cache validity time to 100 seconds, beyond the static resource server (source server) ‘s max-age = 20.

First request

We use the refresh function to refresh the browser, and within 20 seconds we consistently get HIT status, indicating a HIT to the proxy server cache. EXPIRED after 20 seconds indicates that the proxy responded to the instructions of the static resource server (the source server) to invalidate the local proxy, and that the local cache time of 100 seconds set by the proxy server is ignored.

This time we also used the browser refresh function to force the browser to check the validity of the cache on the server, which means that in the above test, the browser ignored max-age and went to the server every time.

Conclusion: The new max-age controls the cache duration retained by the proxy server. The local proxy ignores the configured cache duration and uses the max-age delivered by the static resource server (source server) as the cache duration.

To test how browsers use local caching, let’s experiment with a WebView on Android, because webViews don’t have a refresh button (unless you build one yourself).

First open;

And then we open it up and then we open it up again every two seconds;

As you can see, the WebView doesn’t ask the server to download the site’s index.html again for 20 seconds. In the screenshot above, every time favicon.ico is displayed, I open a link to the site. Webviews are looking for a server to download this resource.

More than 20 seconds later, the WebView sends a request, and this time the server returns 304, asking the client to continue the display using cache, and this time the max-age instruction is displayed. After this verification, the WebView will extend the validity period of the local cache for another 20 seconds. After the next 20 seconds, the WebView will initiate a new cache authentication request.

Summary: The client WebView caches index.html under the public directive, and then does not make any network requests to validate the resource for as long as max-age requires.

In a case of the official website mall, after the website went online, no cache-Control protocol was configured for operation and maintenance. Under the default public mode, the client webview used local cache all the time, and the developer found that the client could not update the page in time after the front-end version was released. A timestamp is manually inserted at the end of each open url to force the url to change and invalidate the browser cache. This problem can be solved by using nocache or max-age as cache-control.

In addition to max-age, cache-control can also add the following controls on the basis of cacheability control instructions;

no-transform

The source server tells the client that the client cannot make changes to the file when caching data, such as compression, format modification, etc.

must-revalidate

The source server tells the client that once the resource expires, it cannot be used until it initiates validation to the static resource server (source server).

proxy-revalidate

Same as must-revalidate, only for shared caches (such as proxies).

max-age=

The static resource server (source server) tells the client that for X seconds, the client does not need to validate the cache and can use it directly.

s-maxage=

The static resource server (source server) tells the proxy server that it can use the cache for X seconds without validation, but the client ignores this instruction.

Again, how does the server determine whether the browser’s cache is valid during validation?

The client browser, whenever it has a chance to access the server, tells the server when my local cache was last-modified and what the data is (ETag), so that the server can use these two values to determine whether the client cache is valid or not.

Let’s simulate a front-end publishing operation to modify the contents of index.html. The request is then made using the Android WebView.

This time the server generously returned 200 and data. Take a close look at the request and response headers;

  • The if-none-match in the request header is the same as the ETag returned by the last server;

  • The if-modified-match in the request header is actually the last-modified that was returned by the Last server;

Neither of these values now correspond to the server, so the server returns the latest data and the 200 status code with the latest Etag, last-Modified. The next time the client requests it, it brings the latest Etag and last-Modified.

In some cases, the server may return incomplete validation fields, such as missing either Etag or Last-Modified, and the cache validation in this case may be at risk.

In a case on PC’s official website, the source site server returned the Etag and Last-Modified values of the static resource, but the proxy server, or CDN vendor, removed the Etag when it returned, resulting in the absence of Etag verification. Under normal circumstances, the server only uses the last modification time of the file for cache verification. However, there is such a user, his browser in the cache of static resources damaged, the browser each read out of the resource can not be used, it can not render the page normally, but every time with the server to verify the resource, the server will still inform the client 304 (cache available). In this scenario, the user will never be able to open the file as long as the source site server does not update the resource, i.e., the last-Modified.

Having said that, you’ve got a little bit of the whole downstream and interaction part of the caching protocol. That leaves the upstream part of the caching protocol, where cache-control is written to the browser’s access headers.

As we mentioned earlier, a browser refresh request is actually a **cache-control: max-age = 0 in the request header. ** This tells the server that the client wants to receive a cache with a lifetime of no more than 0 seconds. Usually the source server, especially the static resource server, will return 200 or 304, depending on the client’s cache.

4.4.11 Cacheability control in request headers

no-cache

Tell the proxy server not to use caching directly and to request a request from the source server.

no-store

None of the files are cached locally or in temporary folders.

max-age

Tell the server that the client wants to receive a resource that exists for no more than X seconds.

max-statle

Tell the server that the client is willing to accept a resource that exceeds the cache time for X seconds.

min-fresh

Tell the server that the client wants to receive a resource that has been updated in less than X seconds.

no-transform

Inform the proxy server that the proxy server is not allowed to compress and transform resources. For example, some proxy servers will compress and transform images.

only-if-cached

Tell the proxy server that if the proxy server has cached content, it can give it to the proxy server instead of asking for it from the source server.

The cache control in the request header is used very rarely, so I won’t read too much about it, if you are interested.

Five, the summary

The CACHE-control protocol of HTTP defines the cache interaction logic between client, proxy server and source server. As for client development, some cache-related problems often occur and you cannot start troubleshooting them. By learning this part, you can quickly analyze and locate these problems.

After the front-end students are familiar with the logic of cache-control, they can also discuss their cache requirements with operation and maintenance according to the form of business, which can effectively reduce the pressure of the server and user traffic and improve the speed of webpage opening.

Author: Chen Long, Vivo Internet Client Team