Search code examples
create-react-appprogressive-web-appscloudflareworkbox

When do Workbox / create-react-app PWAs update to new static assets?


I have a PWA which was made with create-react-app. The codebase of the PWA is regularly updated and we ship new versions of the app daily.

I've noticed different behaviour with regards updates of our PWA in two different use cases. I wanted to talk through what I've noticed and I'm hoping someone with workbox expertise can explain the why 😊

I should say that we optimise for clients updating as soon as possible with this:

          if ('serviceWorker' in navigator) {
            navigator.serviceWorker.addEventListener('controllerchange', function () {
              if (confirm('New version of app available; update now?')) window.location.reload();
            });
          }  

Desktop Chrome Usage

Every time we release, anyone accessing the app subsequently sees the "New version of app available" prompt and gets to upgrade. This version is typically used by people who work access the app via the intranet of our company.

Android Added to Home Screen PWAs

The other use case is the same app installed on Android phones. This version is accessed on the internet behind Cloudflare.

We've never yet seen the "New version of app available" in this context. Rather, at some point the app updates and we see new content.

The Question

So the question is: what triggers the update of the PWA in the Added to Home Screen context? I'm not certain but I've some circumstantial evidence to offer:

Updates in this context seem to happen within 7 days. Interestingly, static assets (JS / CSS / HTML) are cached for 7 days in our app.

I'm wondering if maybe Cloudflare is a reason here? Or the static asset cache policy? Or both? Or something else?

If someone could shed some light I'd love to learn!


Solution

  • It's been a while since I've looked at the create-react-app codebase. In general, we recommend this recipe for detecting when there's a new service worker that's been installed and is in the waiting state. It uses workbox-window to simplify some of the communication between the service worker and the client page—like telling the service worker to invoke skipWaiting() so that the new service worker will get a chance to active, and then reloading the page once it does.

    There's nothing specific to adding a web app to the Android home screen that would cause the service worker update check behavior to be different vs. Desktop Chrome. In both case, a check for an updated service worker happens for the reasons outlined in this section of the "Service Worker Lifecycle" guide.

    If you're noticing differences between the environments, then yes, it sounds like CDN caching could explain it. In particular, if your service-worker.js (or whatever it's called) is being served via the CDN, you need to make sure that the CDN purges it's old copy of the file and replaces it with the version from your most recent build each and every time you deploy. If you're not doing that, it would explain the behavior you're seeing.