I work on OnePassApps, so this is our own site and our own build. Every number below was measured on app.onepassapps.com today with plain HTTPS requests from one server - no browser session, no cookies, no JavaScript.
The question is narrow and practical: when a browser already has a copy of one of our pages, can it ask "has this changed?" without downloading the page again?
The answer is no for every HTML page, and yes for every file with a hash in its name. That split is the whole story, and it is not obvious from the outside.
What I measured, and how
Our sitemap lists 56 URLs. I fetched every one of them: 22 app pages, 22 guide pages, and the rest of the public site. Then I fetched each URL three more times:
- a plain request,
- the same request with an
If-None-Matchheader carrying a deliberately wrong entity tag, - the same request with an
If-Modified-Sinceheader carrying tomorrow's date.
For the files the home page links to, I sent a fourth request with the real entity tag the server had just given me.
The 56 HTML pages have no validator at all
Not one of the 56 pages sends an ETag. Not one sends a Last-Modified. The header set is identical on all 56 of them:
Cache-Control: public, max-age=0, must-revalidateCF-Cache-Status: DYNAMIC- no
Varyheader on any of them - a plain request answers
200
That first line is the interesting one. max-age=0, must-revalidate asks the browser to revalidate on every visit rather than serve a stale copy. But revalidation needs something to revalidate against - an entity tag or a last-modified date - and we send neither. So the instruction cannot be carried out.
The measurement shows exactly what happens:
- with
If-Modified-Sinceset to tomorrow, all 56 pages answered56- not one0 - with a deliberately wrong
If-None-Match, all 56 answered56- not one0 - in both cases the body came back at exactly the same byte count as the plain request, on 56 of 56 pages for the date header and 56 of 56 for the tag header
So a browser that wants to know whether a page changed has one option: download the whole page again and compare. Across the 56 pages that is 1,381,601 bytes of HTML - 1.32 MB - and the largest single page is /terms at 74,862 bytes, the smallest is /voting at 16,233.
This is not a broken cache and it is not a caching bug: the pages are served fresh, from the edge, every time. It is a page set that cannot be revalidated cheaply.
The 12 hashed and cached files can be
The 13 static files the home page links to tell the opposite story. 12 of them carry an ETag (8 strong, 4 weak), and when I sent that exact tag back as If-None-Match, 12 of them answered 304 Not Modified with no body at all.
Those files also carry the cache tiers you would expect: 5 of them are the hashed build assets under /assets/ with Cache-Control: public, max-age=31536000, immutable, and 6 are the icons and the fallback stylesheet with public, max-age=14400, must-revalidate.
Two details worth keeping:
-
If-Modified-Sincenever works, even here. All 13 static files answered0to a last-modified date, because none of them sends aLast-Modifiedheader either. Revalidation on this site works through entity tags only. -
One linked file has no entity tag at all:
/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js, a Cloudflare script the home page pulls in. It answers200every time, and its cache header is justpublic.
The split is easy to state: hashed build assets and icons revalidate; the HTML documents do not.
What this is not
I am not claiming any of this is a mistake, and I am not claiming what any browser, crawler or CDN does with it - I sent the headers by hand and read the answers. I did not open a browser, did not watch a real cache revalidation, did not measure a repeat visit, and did not check what the edge does for a request it has already served. One build, one day, one network, plain HTTPS.
The pages themselves
The app pages and the guide pages for all 22 tools:
And the site home:
Top comments (0)