The resources that work best with caching are static immutable files whose contents never change. And for resources that
do
change, it is a common best practice to change the URL each time the content changes, so that the URL unit can be cached for a longer period.
As an example, consider the following HTML:
<
script
src
=
"
bundle.js
"
>
</
script
>
<
link
rel
=
"
stylesheet
"
href
=
"
build.css
"
/>
<
body
>
hello
</
body
>
In modern web development, JavaScript and CSS resources are frequently updated as development progresses. Also, if the versions of JavaScript and CSS resources that a client uses are out of sync, the display will break.
So the HTML above makes it difficult to cache
bundle.js
and
build.css
with
max-age
.
Therefore, you can serve the JavaScript and CSS with URLs that include a changing part based on a version number or hash value. Some of the ways to do that are shown below.
# version in filename
bundle.v123.js
# version in query
bundle.js?v=123
# hash in filename
bundle.YsAIAAAA-QG4G6kCMAMBAAAAAAAoK.js
# hash in query
bundle.js?v=YsAIAAAA-QG4G6kCMAMBAAAAAAAoK
Since the cache distinguishes resources from one another based on their URLs, the cache will not be reused again if the URL changes when a resource is updated.
<
script
src
=
"
bundle.v123.js
"
>
</
script
>
<
link
rel
=
"
stylesheet
"
href
=
"
build.v123.css
"
/>
<
body
>
hello
</
body
>
With that design, both JavaScript and CSS resources can be cached for a long time. So how long should
max-age
be set to? The QPACK specification provides an answer to that question.
QPACK
is a standard for compressing HTTP header fields, with tables of commonly-used field values defined.
Some commonly-used cache-header values are shown below.
36 cache-control max-age=0
37 cache-control max-age=604800
38 cache-control max-age=2592000
39 cache-control no-cache
40 cache-control no-store
41 cache-control public, max-age=31536000
If you select one of those numbered options, you can compress values in 1 byte when transferred via HTTP3.
Numbers
37
,
38
, and
41
are for periods of one week, one month, and one year.
Because the cache removes old entries when new entries are saved, the probability that a stored response still exists after one week is not that high ? even if
max-age
is set to 1 week. Therefore, in practice, it does not make much difference which one you choose.
Note that number
41
has the longest
max-age
(1 year), but with
public
.
The
public
value has the effect of making the response storable even if the
Authorization
header is present.
Note:
The
public
directive should only be used if there is a need to store the response when the
Authorization
header is set.
It is not required otherwise, because a response will be stored in the shared cache as long as
max-age
is given.
So if the response is personalized with basic authentication, the presence of
public
may cause problems. If you are concerned about that, you can choose the second-longest value,
38
(1 month).
# response for bundle.v123.js
# If you never personalize responses via Authorization
# If you can't be certain