Caching workflow between clients and servers
While as frontend developers we seldom do anything in regards to caching, as a full-stack developer you need a good understanding of how caching works in the browser and on the server. Before embarking on a full-stack path, the only time I needed to do anything related to caching was when I wanted a new version of a script or stylesheet to be picked up by users, which I did by adding a query parameter to the end of the path:
<link rel="stylesheet" href="style.css?v=1.2.3">
This invalidates browser's cache, forcing browser to fetch a new version of the resource from the server. But what happens if the resource path doesn't change? Then a set of headers in request and response objects define how caching works. These headers are Cache-Control
and ETag
on response object and If-None-Match
on request object.
The first time a browser requests a resource, the server returns a response with 200
status. Server generates a unique hash from response body and sends it in a ETag header. Below is an example of a response with corresponding headers:
// response
Cache-Control: public, max-age=0, must-revalidate
Etag: "a6254f652913ca53429b315c9167b3d2"
Since max-age is set to 0 seconds, browsers consider the resource as stale in future requests and use the value of ETag in a If-None-Match
header to send a so-called conditional request to the server:
// request
If-None-Match: "a6254f652913ca53429b315c9167b3d2"
When server receives such request it checks whether the ETag it has for the current version of the resource matches the value of ETag sent in If-None-Match
header and if it does, server sends a response with 304
status and no body, telling the browser it can use the resource from the cache. Note that ETag header is not sent in 304 responses.
Related Links: