Separate files by responsibility
An HTML document points to the JavaScript, CSS and images needed for a release. A fingerprinted asset has a URL tied to a particular content version. Those responsibilities suggest different caching behavior: a versioned file can be reused aggressively, while the document that selects current asset URLs must be able to learn about new releases.
Make the filename meaningful
If a stylesheet changes from site.a12.css to site.b34.css, the browser requests a new address rather than relying on an old cached response to update itself. The build must actually change the filename when the contents change. Appending an arbitrary constant version query that never advances provides a label, not a working content-versioning strategy.
Walk through a release
Imagine release A serves HTML referencing app.a1.js. Release B uploads app.b2.js and then publishes HTML referencing it. Keep app.a1.js available long enough for older documents or open sessions that still request it. Deleting all previous assets immediately can turn a well-cached old document into a broken interface, even when the newest homepage appears correct.
Distinguish revalidation from prohibition
Cache-Control directives describe storage and reuse rules with different meanings. For example, no-cache permits storage but requires validation before reuse, whereas no-store asks caches not to store the response. Choose settings based on the resource and privacy requirements rather than applying whichever directive sounds strongest. Inspect actual response headers because host defaults can override assumptions in application code.
Avoid conflicting deployment practices
Do not overwrite a supposedly immutable filename with different bytes. Avoid serving private user-specific responses under a shared public cache policy. Keep compression variants and relevant request headers accounted for in the cache configuration. A long max-age is useful only when the URL and deployment process support the promise that the cached representation remains appropriate.
Measure the warm and cold paths
Test a first visit, a repeat visit and an update from an older release. Check requested URLs, transferred bytes, validation responses and missing assets. Record which layer supplied each response: browser, CDN or origin. Caching success means both efficient reuse and reliable change propagation; a low transfer size is not a win if it keeps the user on obsolete code.
Further reading
Put the idea to work.
Explore free browser tools for images, text and developer workflows.