A year in the cache, for a file that cannot change
Every script we ship carries a content hash in its address, so a browser could keep it a year. Ours re-checked all 138 on every screen. One file fixed it.
Open a back-office screen, then another, and count what the browser asks the server. We counted: a hundred and thirty-eight scripts and two stylesheets, and on every navigation the browser asked about every one of them. "Has this changed?" A hundred and thirty-eight times. The answer was always no.
The reason was a default. The platform that serves our files marks everything
re-check every time unless told otherwise, and nobody had told it
otherwise. Which was odd, because we had already solved the problem the
re-check exists for. Every script and stylesheet we ship is referenced with its
stamp in the address — app.js?v=a1b2c3d4e5 — and the stamp is a
hash of that file's own contents. A file at that address can never change. If
the file changes, so does the address; if it does not change, the address stays
put and the browser keeps what it already had. So the browser could have kept
every one of them for a year and never been wrong.
The fix is a file
One text file beside the assets, five rules long. Scripts and stylesheets: keep for a year, immutable. The service worker: re-check every time, because an old worker kept for a year would keep serving an old till. Screenshots and brand images, which have no version in their address: a day, then refresh in the background. Measured on one back-office screen, the requests that reached the network per load went from a hundred and thirty-eight to none, and the screen's own time from about four hundred milliseconds to under two hundred. A first-ever visit still fetches everything once. Every page after it does not.
The rule it creates
A year-long cache has one condition: the address must change whenever the file does. We had the version stamp; we had not had the discipline, because nothing enforced it. The day before this change, a one-line fix to a script had been re-uploaded under the same version — harmless then, because every browser re-checked. Under the new rule that same fix would never reach a browser that already held the file. So the rule is now written down where the deploy steps live, and a test reads the shells for any script or stylesheet referenced without a version. An edit to anything in those folders bumps the version, even a hotfix, even a comma.
There is a general shape in this. A default that says "re-check every time" is the safe choice for a thing that might change under the same name. It is pure cost for a thing whose name changes with it. Knowing which one you have is the whole decision.