Master HTTP Caching: Practical Rules for Static and Dynamic Resources
This guide explains why HTTP caching can be tricky, then provides concise, actionable rules for static assets and dynamic content, covering Cache‑Control, Expires, ETag, Last‑Modified, Vary headers, and how browsers handle refreshes to improve web performance.
Static Resources
Files that never change—JavaScript, CSS, images, and other binary assets—should always be versioned so that any modification results in a new URL.
Embed a fingerprint in the filename or path (avoid query strings) and ensure the generated URL is longer than eight distinct characters.
Use the following HTTP headers:
Cache-Control: public, max-age=31536000
Expires: (one year from now)
ETag: (content‑based)
Last-Modified: (past timestamp)
Vary: Accept-EncodingThese settings are sufficient for static assets.
Dynamic Resources
For resources that require freshness or contain private data, different caching directives are needed.
For publicly cacheable, frequently changing data (e.g., stock quotes):
Cache-Control: public, max-age=0
Expires: (current time)
ETag: (content‑based)
Last-Modified: (past timestamp)
Vary: Accept-EncodingThis allows browsers and proxies to cache the response but forces a validation on each request.
If stricter control is required—e.g., always revalidate even when the user navigates back/forward—use: Cache-Control: public, no-cache, no-store When a resource can stay fresh for at least five minutes, apply: Cache-Control: public, max-age=300 To enforce revalidation after that period, add must-revalidate:
Cache-Control: public, max-age=300, must-revalidateFor private or user‑specific content, replace public with private to prevent proxy caching:
Cache-Control: private, …Cache‑Control and Expires
When both Cache-Control and Expires are present, Cache-Control takes precedence. Using both improves compatibility across browsers, but their time values should match to avoid confusion.
Reference: Expires vs. Cache‑Control: max-age
ETag and Last‑Modified
Browsers store the values of ETag and Last-Modified and send them back in conditional requests via If-None-Match and If-Modified-Since. Validation only occurs when the resource is considered stale.
Most browsers send both headers when possible.
Reference: What takes precedence: the ETag or Last‑Modified HTTP header?
A common recommendation is to avoid ETag, but this is not universally optimal. Properly generated ETags (e.g., based on inode, size, and modification time) can provide precise change detection, though in load‑balanced environments they may become inconsistent, leading some to disable them entirely.
Reference: Should your site be using etags or not?
Manual Refresh (Ctrl‑R)
Pressing Ctrl‑R forces the browser to send a request like:
Cache-Control: max-age=0
If-None-Match: …
If-Modified-Since: …This works with both origin and proxy servers; a 304 response means the cached content is reused.
Vary: Accept‑Encoding
The Vary: Accept-Encoding header ensures that compressed (gzip) and uncompressed versions are cached separately, preventing browsers that don’t support gzip from receiving compressed data.
Internet Explorer does not cache resources with a Vary header unless its value is Accept-Encoding or User-Agent, so including this header improves caching in IE.
Translated from Bryan Tsai’s "Http Caching".
References
Increasing Application Performance with HTTP Cache Headers
Things Caches Do
Google Developers: HTTP Caching
Google Developers: Optimize Caching
Caching Tutorial for Web Authors and Webmasters
Cache Control Directives Demystified
What are the hard and fast rules for Cache Control?
What’s the difference between Cache-Control: max-age=0 and no-cache?
HTTP Cache Control max-age, must-revalidate
Difference between no-cache and must-revalidate
Caching Improvements in Internet Explorer 9
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Aotu Lab
Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
