Cache headers on static assets
A hashed filename lets you cache an asset for a year safely. The header to send, why immutable matters, and what not to apply it to.
What it is
This check looks at the static assets a page loaded — stylesheets, scripts, images, fonts — and asks whether each one came back with a Cache-Control header that lets the browser keep it.
An asset with no caching directive is re-validated or re-downloaded on the next visit. The file did not change; the browser simply has no basis for assuming it did not.
Why it matters
It is the cheapest performance work available, because it makes the second visit fast without making the first one slower. Nothing is re-encoded, no code is refactored, and the asset that does not get requested is the fastest one.
The reason a one-year max-age is safe is the content hash in the filename. When the file changes the hash changes, so the URL changes, so the cached copy is never the stale one — you are not betting that the file will not change, you are making that question irrelevant. immutable goes further and tells the browser not to revalidate even on a reload.
How to fix it
with a reference doclocation ~* \.(css|js|png|jpg|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}<FilesMatch "\.(css|js|png|jpg|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>async headers() {
return [{
source: '/static/:path*',
headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }]
}];
}/static/*
Cache-Control: public, max-age=31536000, immutableRelated checks
4This is one of the 75 checks the scanner runs. See what we check for the full list, every severity weight, and how the score is computed from them.