Browser Caching Explained: Cache-Control, ETag, and CDN Tuning

性能优化(Updated May 28, 2026)

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=123 and ?v=456 are different cache entries
  • Requests with Accept-Language may 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

  1. Chrome DevTools → Network: Size column ((disk cache) / (memory cache) / actual size)
  2. Response Headers: Check Cache-Control, ETag, Age
  3. 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 →

#HTTP缓存#CDN#Cache-Control#ETag#性能优化