Is it possible to enable edge caching without browser cache?

cdn
cache
#1

TL;DR: Is it possible to enable edge caching without enabling browser cache?

Hey there. I moved my CDN to Cloudflare yesterday and I’m really impressed with the performance so far.

I have one question regarding caching. My Reactjs app is hosted on S3, and all files with the exception of the HTML files are cached. This is because I want newer version of the app to be ready as soon as possible to my users, without them having to wait for the browser or server cache to expire.

About 90% of the bandwidth and requests are not cached in Cloudflare because there’s no cache-control header on HTML files. Is there a way to have Cloudflare cache HTML files on the edges without having any browser cache? That way I could purge the cache in Cloudflare when new version of the app is out, and not having to worry about browser cache on users.

I tried creating a page rule with edge caching enabled, but that added browser cache as well. I then tried to add browser cache in combination with edge cache, but the lowest browser cache is 30 minutes, which is not what I want. So the big question is: Is it possible to enable edge caching without enabling browser cache?

Thank you!

0 Likes

#2

In general, it is. But you will probably need to configure your server to send the right cache-control headers.

You should set “browser cache” to respect existing headers, then edge cache set to a certain value.

For one, say you have a public resource that currently returns

Cache-Control: public, max-age=691200

What you would need to do is set max-age (the part the browser reads) to 0 (or 1, 30, etc), then add a new directive to the cache-control header, called s-maxage. This is a header only the Cloudflare cache will honor, so that becomes

Cache-Control: public, max-age=1, s-maxage=691200

For more information:

4 Likes

#3

Thanks @Judge for the quick and detailed answer.

I have one follow-up question to your answer. To be absolutely sure I don’t cache HTML files for browsers, would this header be valid for Cloudflare?

s-maxage=600,max-age=1,no-cache,no-store,must-revalidate

Would this cache the HTML files on the Cloudflare edges for 10 minutes, but with almost no cache on browsers?

Thanks.

0 Likes

#4

no-cache means no caching at all (likely at the edge too). the max-age=1 should cause browsers to re-ask for the page, especially if you have must-revalidate, but the thing is… I’m not sure if/how must-revalidate affects the edge cache…

0 Likes

#5

Yeah, this is a bit confusing.

The use case is this:

React apps usually don’t cache the index.html file because it contains references to the JS/CSS files. The bundle files all have unique names (hash) so they can be cached forever.

At the moment Cloudflare is always fetching the index.html file from S3, which makes the performance of the site slower. It could be a lot faster if Cloudflare could cache the index.html on the edges. That way I could just purge the cache during the deployment process.

I think a lot of Reactjs/Angular/Vuejs apps would benefit from this kind of caching mechanism. If only we could force Cloudflare to cache by using s-maxage or something like cf-cache-force in the cache-control header.


What do you think? Could I achieve this by removing the no-cache,no-store,must-revalidate and only use s-maxage=600,max-age=1? Would some browsers cache the index.html for longer than one second? I’m really concerned about some users getting stuck to a particular version of the site for too long.

Thanks again and I really appreciate all the answers so far.

0 Likes

#6

max-age=1 is supposed to query the server… if not for a full fetch then at least for an If-Modified-Since query… I personally don’t send must-revalidate with in my Cache-Control and I have AJAX calls to re-fetch data every 30 seconds, and I didn’t hear complaints (my site’s main business is showing up-to-the-minute data). But this is AJAX, not plain HTML. Rules may be different but I think they shouldn’t be (i.e. if they do, it’s a browser bug)

If you want to be extra sure, what you could do is maybe run after document has finished loading (asynchronously) an extra call to some other file (with max-age=600 and must-revalidate) that contains a unix timestamp, and have the HTML contain the same unix timestamp. If the call returned a value that is different than the one from the HTML, put a bar at the bottom of the page that tells the user that a new version exists, and if they’ld like to reload, perhaps with a link to window.reload(), if you find out that this works to force fetch from server, or suggest user to ctrl+shift+r …

0 Likes

#7

This sounds a lot like what I have been trying to achieve, without any luck.

I’ve been battling CloudFlare cache and page rule’s to get Everything cached at the edge but only Standard caching in the browser.

But I cannot find a way! At least not through CloudFlare alone.

Any time I enable the page rule with Edge Cache TTL and Cache Everything the browser caching also seems to apply.

This seems like it should be a simple thing to do without having to resort to a custom request to check expiry and show the user a message. It is proving to be anything but.

1 Like

#8

I agree, this should definitely be supported by Cloudflare. It would benefit all single page applications such as Reactjs (+ Gatsby), Vuejs, Angularjs and more. All of these frameworks recommend setting the cache-control to no-cache for all HTML files.

I’m working on a ‘hack’ where I basically set this cache-control header to all HTML files:
public,s-maxage=600,max-age=10,must-revalidate

This header should only set the browser cache to 10 seconds, and edge cache to 10 minutes. If everything works correctly then I’ll probably increase the edge cache to a week or more.

0 Likes

#9

Definitely. The site I’m working on is using WordPress. I have gotten around it by allowing WordPress to define the browser caching and setting CloudFlare to respect existing headers. Perhaps this should have been more obvious to me at the start but I was taking the approach of wanting all of the configuration in CloudFlare.

But at least it’s working! Now I just have to document all the nuances of the caching setup between CF and WP so someone doesn’t come along and stuff it up!

1 Like

closed #10

This topic was automatically closed after 30 days. New replies are no longer allowed.

0 Likes