1

I have a React SPA application on S3. I'm fronting that with CloudFront solely to get an SSL certificate with a custom domain - I honestly don't really care about the caching functionality of CloudFront for this, although I suppose it's a nice perk.

Everything works fine, except when I do an update to the S3 bucket, the page remains cached in Chrome. If I clear the application memory in Chrome, it goes out and gets the most recent version.

I'm deploying the app by creating a production build, and then uploading everything to S3 and issuing a CF invalidation:

 echo "Pushing to S3." aws s3 sync --acl public-read ./ s3://${DEPLOY_BUCKET} --metadata-directive REPLACE --cache-control 'max-age=0,public,s-maxage=2' echo "Invalidating CloudFront cache." aws cloudfront create-invalidation --distribution-id ${DEPLOY_DISTRIBUTION} --paths '/' '/index.html' '/login' '/*' 

The request to CloudFront seems to return reasonable headers to me:

accept-ranges: bytes cache-control: max-age=0,public,s-maxage=2 content-length: 716 content-type: text/html date: Wed, 18 May 2022 17:15:36 GMT etag: "660fb0d86eb442f658af12ead96b2c83" last-modified: Wed, 18 May 2022 16:55:25 GMT server: AmazonS3 via: 1.1 ....cloudfront.net (CloudFront) x-amz-cf-id: eLXohvep_...== x-amz-cf-pop: BOS50-C1 x-amz-version-id: 8V0DR... x-cache: Miss from cloudfront 

Specifically - the cache-control header shows a max-age of 0, so I thought that should tell Chrome to not cache things and always go out and check for a new version.

CloudFront is setup to use the origin headers, so it should be pulling those from S3.

What am I missing? How do I get Chrome/CloudFront/S3 to always check for the latest version of the application?

3
  • I should add that in addition to the page not updating, the etag doesn't update either until I clear the application memory in Chrome. Commented May 18, 2022 at 18:37
  • Does your single page application also have a service worker (for use as a PWA)? Those can be tricky with precaching, making debugging standard client caching harder. Commented May 19, 2022 at 5:47
  • hm... It does. Honestly it's a pretty stock implementation of registerServiceWorker() that one of our devs ripped from somewhere. Disabling it seems to get around the problem, but is there a way to get it to respect the cache-control settings? I.e. even if you have this in local cache, if it's older than X you should still try and check for a new version... Commented May 19, 2022 at 14:38

1 Answer 1

1

Since the cache headers on CloudFront are fine, and disabling registerServiceWorker() fixes your caching issues, we can point blame to the service worker keeping stale content.

registerServiceWorker() is likely from react-scripts < 4.0.0, which doesn't allow you to configure the service worker without ejecting or using a workaround. If you cannot upgrade, you may simply just want to unregister or remove the service worker.

If you upgrade to react-scripts >= 4.0.0, you can modify the workbox config from the PWA Create React App template to use the NetworkFirst Workbox strategy. After upgrading, the precache and the waiting state of the service worker may still be too aggressive for your liking, in which case you should PWA"" rel="nofollow noreferrer">see if someone ran into the same PWA issue.

Learn more about progressive web apps in Create React App

Learn more about how to troubleshoot Workbox

Sign up to request clarification or add additional context in comments.

1 Comment

This is fantastic @evelynhathaway thank you. For now, we're just going to leave things disabled, as I'm not quite sure why the developer added the service worker to begin with. But this is great stuff if we need to add it back in.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.