Serve Static Assets With an Efficient Cache Policy
The first visit to a page can only be so fast, but the second visit should be much faster, because the browser already has most of the assets on disk. This audit checks whether your caching headers actually let that happen.
What it means
Lighthouse inspects the caching headers (Cache-Control, Expires) on every static asset: images, CSS, JavaScript, fonts. Any asset with a short or missing cache lifetime gets flagged, because the browser has to re-request it (at best getting a cheap 304 Not Modified, at worst a full re-download) on every single repeat visit.
Why it matters
This is one of the few audits that mostly affects returning visitors rather than first-time ones, but for any site with meaningful repeat traffic (which is most sites), that's a large share of total page loads. A short TTL means those repeat visitors keep paying network cost for files that haven't changed since their last visit, which is pure waste.
How to fix it
Set a long max-age and immutable on assets that never change once deployed, combined with cache-busting filenames so a new deploy is still picked up correctly:
# .htaccess
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|webp|avif|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
- The
immutabledirective tells the browser it doesn't even need to revalidate with the server before the cache expires, which skips an extra round trip on repeat visits within the cache window. - This only works safely if the filename changes whenever the content changes, which is why build tools fingerprint output files with a content hash:
app.a1b2c3d4.cssinstead ofapp.css. If the filename never changes, a long cache lifetime means visitors could keep an outdated file for a year. - HTML documents themselves usually should not get a long cache lifetime, since they're what reference the fingerprinted asset URLs and need to be fetched fresh (or revalidated) to pick up a new deploy. That first HTML response is a separate problem, covered in reducing server response time.
How to verify
Re-test the page; the audit should show no assets with a short TTL remaining. In DevTools' Network tab, reload the page a second time and confirm static assets show "(disk cache)" or "(memory cache)" in the Size column instead of a real network transfer.
Test your site
Run a free scan to see whether this audit applies to your pages, on mobile and desktop, with lab and field data side by side.
Run a free test