How Does the HTTP Caching Mechanism Work?
January 20, 2023
If you want to speed up web applications, caching is a strategy that is often used. When we have already requested a certain resource from the backend, such as a piece of data or an image, if the resource will not change in the next time we request it, it will be a waste of network bandwidth. On the contrary, if we save the requested resource when we request it for the first time, the resource can be used directly in the next request, which can reduce unnecessary requests. And this is the concept of caching.
Caching can be applied in many places, such as in the client, DNS, server, database, etc (this article from AWS provides a good overview). As a front-end engineer, HTTP caching mechanism is often asked in the interview. We hope that after reading this article, you can explain it clearly when you are asked "Please explain the HTTP caching mechanism" in your next interview.
Where is HTTP caching used? Why use HTTP caching?
The cache is a place where we temporarily store resources (such as a piece of data, an image), so when we need these resources next time, we don’t need to request them again. Instead, we can get them directly from the cache. In the context of HTTP caching, this temporary storage place is the browser.
For example, when a user visits LV's official website today, the pictures and prices of the products on the official website will not change quickly. When visiting the website for the first time, the client side requests LV product;s pictures, descriptions, and prices from the server, and cache them (put them somewhere in the browser memory). No more requests to the server are required when the user visit the website next time.
There are several caching benefits in doing so, and it is also the reason why we use caching
- <b>Reduce the number of requests:</b>We use the previously stored data directly from the cache, which can reduce the burden on the server and database.
- <b>Speed up resource loading:</b> it takes time to request data from the server, since we need to wait for the network to transmit data. By directly using data from the cache in the browser, you do not have to wait for the time of data transmission. Thus, it will be much faster.
How to configure HTTP caching
We have talked about the benefits of HTTP caching, but how to set it up in practice? This is a common follow-up question during the interview, and there are several ways to set up HTTP caching:
Expires
The first way is to add Expires
in the HTTP Response header, for example:
Expires: Tue, 18 Jul 2022 16:07:23 GMT
When the browser receives the response data, it will store the data in the cache first, and the next time the user sends the same request, the browser will see whether the current time has reached the time set by Expires
, if not, it will get data directly from the cache instead of sending requests.
cache-control
Since Expires
is an older method, few people actually use it now. Most people use cache-control
. cache-control
is not to directly set a time point when the cache expires, but to set the effective time of the cache. For example, the following line of code is to set the cache validity period to 60 seconds. So after the first request gets a response, within 60 seconds, if the same request is sent, the browser will directly get the cache data instead of sending the request to the server.
cache-control: max-age=60
cache-control Q&A
Regarding the cache-control
, there are some common follow-up questions that are often asked in interviews. The questions are listed below. There will be answers below, but you can think about it for yourself first to see if you know the answers to these questions.
- What should I use if I only want the client to be cached, but I don’t want other layers such as the proxy server in the middle to be cached?
- Conversely, if I want the proxy server to also be able to cache data from the backend, what should I use?
- Because the browser may automatically cache in many cases, if I don’t want to have a cache at all, and I want the content to be always up-to-date, then what should I use?
- What is the difference between
cache-control: no-store
andcache-control: no-cache
?
The answers to the above questions are
cache-control: private
cache-control: public
cache-control: no-store
cache-control: no-store
means not to cache. Andcache-control: no-cache
means to cache, but every request must be revalidated. In other words, it will still ask whether the server content has been updated every time, and use the cache if it is not updated. See this discussion for details.
How to re-authenticate after HTTP cache expires?
As mentioned above, we can use cache-control: max-age
to set how long it takes for the cache to expire; However, sometimes when the cache expires, the data on the server side might not be expired. In other words, there is no update. Thus, the cache can still be used. Is there a way for us to continue using the cache under this circumstance? Yes, this is also called validation. And HTTP caching has two main ways to do this.
ETag (with If-None-Match)
The first way is to put ETag (short for entity tag) in the header of the response. This ETag will be a unique value, such as ETag: "686897696a7c876b7e"
; if the backend data changes, the ETag will change. If the server puts ETag in the response header, then when the browser makes a request later, it will add the field If-None-Match
to the header of the request.
Then, the server side receives the request and checks whether the ETag in If-None_match
is the same as the current ETag. If they are the same, it means that the data on the backend has not changed (because if the data has changed, the ETag will change accordingly). Then the server only need to pass a 304 Not Modified to the front end, and the browser will know that the data has not changed after receiving the 304 , so the client side can continue using the cache. And if the backend compares the ETag and finds a change, it will not return 304, but return a packet of new data.
Last-Modified (with If-Modified-Since)
The second way is to add Last-Modified
to the response header of the server, and mark the time when the resource was last modified, for example Last-Modified: 2021-11-07 21:32:16
. When the browser receives a response with Last-Modified
, subsequent requests will bring If-Modified-Since
, and then bring the previously received time, such as If-Modified-Since: 2021- 11-07 21:32:16
.
The server receives the request with If-Modified-Since
and compares the time. If the time to update the resource has not changed, it can return 304 Not Modified to the client. If it has changed, the server will return 200 and new data.