How to Cache Assets for Instant Repeat Visits

A returning visitor should download almost nothing. Most sites make them redownload everything.

How to Cache Assets for Instant Repeat Visits — Troiana insight cover

In short

Cache versioned static assets (JS, CSS, images with a hash in the filename) aggressively and permanently, since a filename change guarantees freshness — but cache HTML documents conservatively or not at all, since they're what need to update when content changes.

The core idea behind good caching

A browser cache stores a copy of a file locally so a repeat visit doesn't need to redownload it. The entire strategy comes down to one distinction: assets that never change once published (a specific version of a JS bundle, a specific image) can be cached forever, while content that does change (the HTML of a page) needs a strategy that balances freshness against caching.

Versioned filenames make aggressive caching safe

The key technique that makes "cache forever" safe: include a content hash in the filename (app.a3f9c2.js instead of app.js). When the file's content changes, its hash — and therefore its filename — changes too, so a new deploy naturally produces a new URL. This means you can set an extremely long cache lifetime on the old filename with zero risk, because it will genuinely never change; any actual update ships under a new name.

Setting cache headers correctly

For versioned static assets: Cache-Control: public, max-age=31536000, immutable — cache for a year, and tell the browser not to even bother re-validating, since the immutable flag promises the content will never change under this URL.

For the HTML document itself: something much shorter, or no-cache (which, despite the name, allows caching but forces revalidation before use) — since HTML is exactly the thing that needs to reflect your latest content.

The common mistake: caching HTML too aggressively

The most common caching bug is applying a long max-age to HTML documents, which means visitors keep seeing a stale version of the page for hours or days after you've published an update — sometimes not even a hard refresh fixes it, since the browser doesn't know to check. HTML should generally be cached conservatively; static assets should be cached aggressively. Mixing these up in either direction causes real problems.

Service workers for a further layer

For applications that benefit from offline capability or want to guarantee instant repeat loads even on flaky connections, a service worker can cache assets at the application layer, serving them from cache first and updating in the background. This adds complexity and isn't necessary for most content sites, but it's the right tool for app-like products where offline resilience matters.

CDN caching versus browser caching

A CDN caches assets at edge servers geographically close to visitors, which speeds up delivery even on a visitor's very first request (before their browser has anything cached locally). Browser caching and CDN caching work together — the CDN reduces latency on every request; the browser cache eliminates the request entirely on repeat visits.

Verifying your caching is actually working

Open browser dev tools' Network tab on a repeat page load and check the "Size" column — assets served from cache typically show "(disk cache)" or "(memory cache)" instead of a byte count. If static assets are re-downloading on every visit, the cache headers aren't configured correctly.

A practical setup

Build pipeline outputs versioned filenames for all static assets (most modern bundlers do this by default) → set immutable long-lived caching on those → set short or no-cache on HTML documents → optionally add CDN caching in front of everything. This combination gets a returning visitor to near-instant load with minimal ongoing effort.

More from our insights: A Complete Guide to Web Performance · How to Lazy-Load Images the Right Way.

Common questions

Why is it safe to cache a file forever if it has a hash in the filename?

Because any change to the file's content produces a different hash and therefore a different filename — the old URL genuinely never changes again, so caching it permanently carries no staleness risk.

Should I cache HTML pages the same way as JS and CSS?

No — HTML is what needs to reflect your latest content, so it should be cached conservatively (short max-age or no-cache), while versioned static assets can be cached aggressively and permanently.

How do I check if my caching is actually working?

Open your browser's dev tools Network tab and reload the page — correctly cached assets show as served from disk or memory cache instead of re-downloading with a byte count.

Have something worth building right?