Workers with static assets - asset caching?

I have set up a React Router v7 site with CF Workers. The setup uses the static assets function in wrangler.json ("assets" parameter), which uploads all static assets that are compiled and bundled with Vite. They are all fingerprinted, so I would like to have the Cache-Control header to for example Cache-Control: max-age=31536000, immutable. However - when testing the setup, all static assets are on first load (empty cache) delivered with a response of 200 together with Cache-Control: public, max-age=0, must-revalidate - which my understanding is that Cloudflare tells the browser to not cache anything. On next refresh, the browser sends with a If-None-Match: ETag header in the request - and Cloudflare responds with a 304, which causes the browser to use the in-memory version of the asset. To me, this seems like the static assets are just being cached by "luck"? If the browser had not cached assets regardless of cache-control header, no static assets would be cached? I also tried to set up a cache control rule on the domain on the URI path /assets/* to override the cache header for Edge TTL and Browser TTL to 1 year. Nothing changes in the Cache-Control header due to this. Any suggestions on what I am doing wrong? Cloudflare Dashboard reports 0.5%-3% of requests are being cached over past 1-30 days, so this worries me to not get "right" before launching the site to the public - a lot less than what I would expect for a site that will be 99% static.
8 Replies
Walshy
Walshyโ€ข3w ago
Workers Assets is already caching assets, unfortunately it just doesn't reflect in the zone analytics but be rest assured we are. We also do indeed make use of etags for browser caching, the way it's currently setup is the browser will cache but make sure to check-in with the server that it's cached value is the one we expect. Otherwise you could end up with old stale assets being served which is especially bad for html files, less bad for js but it depends on how it's being named (is it content hashed)
svend
svendOPโ€ข3w ago
Thanks for the quick reply! Good to hear that you are caching the assets (on the edge I assume), but it would be even better if there is a mechanism to tell the browser to cache the assets. Relying on the browser incidentally still having the file in-memory to use ETags seems.. iffy? In my case, all static assets are content hashed / fingerprinted.
Walshy
Walshyโ€ข3w ago
You can invoke your Worker and set a cache-control header. Us as a platform doing it by default isn't a great idea because it can cause problems (assets being stale) The current etag mechasism is native browser supported and still very fast
svend
svendOPโ€ข3w ago
Yes thought about it, and not going down that road ๐Ÿ˜น Not sure I am able to bring my point across here - but the way I understand it, the current ETag mechanism only works because the browser chose to save a copy of the assets on its own initiative after the first request to the site - even if the Cache-Control header told the browser to not cache the asset. I have no control of how long that cache is kept - could be until next browser restart, 5 minutes - who knows?
Walshy
Walshyโ€ข3w ago
on its own initiative
that's just the way etag works, it isn't required to send a cache-control header, cache-control is a different mechanism which can accompany. Cache-Control would mean the browser would not check with the server to know if the one it has is correct, so if it cached let's say index.html - the browser could serve a stale version while the server wants to serve the fresh one. Etag explicitly caches but does a "is this still correct" check with the server - it's why we implemented this ๐Ÿ™‚ I'm not sure how long Chrome keeps it without additional info like a cache-control header, i assume it falls back to some default time. All I'll really say is it's hard to get the balance right here, we want fast but we also need to make sure things don't break Happy to hear suggestions if we can improve this without breaking. Not sure what a Cache-Control with always revalidate would be like, I think it'd be requesting the full body each time (essentially just voiding the browser cache)
svend
svendOPโ€ข3w ago
"Cache-Control with always revalidate " is exactly what Cloudflare is responding with today and partially why I am a bit concerned and reaching out here ๐Ÿ™‚
No description
svend
svendOPโ€ข3w ago
One "good enough" solution would be to have the "Caching / Cache Rule" setting actually take effect so that I could manually set up some rules. The attached rules seem to have no effect from what I could see.
No description
svend
svendOPโ€ข3w ago
Another "good enough" solution would be to start using the _headers file support in CF Pages also for Worker Assets: https://developers.cloudflare.com/pages/configuration/headers/
Cloudflare Docs
Headers ยท Cloudflare Pages docs
To attach headers to Cloudflare Pages responses, create a _headers plain text file in the output folder of your project. It is usually the folder that contains the deploy-ready HTML files and assets generated by the build, such as favicons. Changes to headers will be updated to your website at build time. Make sure you commit and push the file t...

Did you find this page helpful?