The fastest request is the one never made. Caching headers are how repeat visits become instant โ and how sites accidentally serve stale files for a year.
The header
Cache-Control: max-age=31536000, immutable # keep 1 year, never re-check Cache-Control: no-cache # keep, but VALIDATE before using Cache-Control: no-store # never keep (banking)
The strategy every real site uses
- HTML โ no-cache: always validated, so users get new releases immediately
- CSS/JS/images โ max-age=1 year + hashed filenames:
app.3f2a9c.jsโ content change โ new hash โ new URL โ cache "busted" naturally. Vite does the hashing automatically
This pair gives instant repeat loads AND instant deployments โ no trade-off.
ETags โ validation on the cheap
# first response: ETag: "abc123" # browser revalidates later: If-None-Match: "abc123" # server: 304 Not Modified (empty body โ bytes saved)
Debugging
Network tab: "(disk cache)" = served locally, 304 = validated-unchanged, 200 with full size = cache miss. "Disable cache" checkbox while developing โ half of all "my change isn't showing" mysteries end there. Your .htaccess Expires block (this site has one) is exactly these headers in Apache form.
โ All Articles