Browser Caching Explained: Cache-Control, ETag, and CDN Tuning
Two Layers of HTTP Caching
Browser requests a resource
↓
① Strong cache (no server round-trip)
Cache-Control: max-age=31536000
↓ expired
② Validation cache (ask server if changed)
ETag / Last-Modified → 304 Not Modified
↓ resource changed
③ Fetch new resource from server → 200 OK
Cache-Control Directives
| Directive | Meaning | Example use |
|---|---|---|
max-age=N |
Use cache for N seconds | JS/CSS (1 year) |
s-maxage=N |
CDN caches for N seconds | HTML (1 day) |
no-cache |
Revalidate ETag every time | API responses |
no-store |
No caching at all | Sensitive data |
immutable |
Content never changes | Hash-named assets |
stale-while-revalidate=N |
Serve stale for N seconds while revalidating | i18n JSON |
ToolsKu cache configuration
# _next/static/chunks/app-abc123.js
Cache-Control: public, max-age=31536000, immutable
# /en/pdf/merge/index.html
Cache-Control: public, max-age=3600, s-maxage=86400
# /i18n/toolClients/en.json
Cache-Control: public, max-age=86400, stale-while-revalidate=604800
ETag Validation Caching
# First request
GET /api/config HTTP/1.1
→ 200 OK
ETag: "abc123"
Cache-Control: no-cache
# Subsequent request
GET /api/config HTTP/1.1
If-None-Match: "abc123"
→ 304 Not Modified (empty body, saves bandwidth)
ETags are derived from a content hash. Unchanged content returns 304 and the browser uses its local copy.
CDN Cache Architecture
ToolsKu is deployed on Alibaba Cloud OSS + CDN:
User requests https://www.toolsku.com/en/
↓
CDN edge (Beijing / Shanghai / Guangzhou)
↓ cache hit → direct response (TTFB ~20ms)
↓ cache miss
OSS origin (Beijing)
↓ return resource + populate CDN cache
CDN → user
Cache key design
CDN keys are usually URL + query string. Watch out for:
?v=123and?v=456are different cache entries- Requests with
Accept-Languagemay split cache (Vary header) - ToolsKu uses path-based locales (
/zh-CN/,/en/) to avoid Vary issues
Common Cache Pitfalls
1. Updated JS but users see the old build
Cause: Old JS is strongly cached; new HTML references new filenames but old JS remains cached.
Fix: Content-hash filenames (Next.js default _next/static/chunks/app-[hash].js). Content change → hash change → natural invalidation.
2. HTML cache hides fresh content
Fix: Shorter max-age + s-maxage on HTML, or actively purge via CDN refresh API.
3. Service Worker cache vs HTTP cache
The Service Worker fetch handler can intercept all requests—priority over HTTP cache. Bump cache version on SW updates and delete old caches.
Cache Debugging Tools
- Chrome DevTools → Network: Size column (
(disk cache)/(memory cache)/ actual size) - Response Headers: Check Cache-Control, ETag, Age
- ToolsKu HTTP status code reference: Understand 200, 304, 404, etc.
Summary
Sound caching is core to web performance. Strong cache + validation cache + CDN edge nodes give ToolsKu TTFB around ~50ms on first paint. Understanding Cache-Control and ETag is fundamental front-end performance work.
Try these browser-local tools — no sign-up required →