10

I've integrated a service worker into our Single Page App built with ReactJS, using the workbox-build package by Google.

I'm having some troubles on the pre-caching of the index.html, specifically the service worker is serving an outdated index.html everytime we release a new build. Since it served an outdated index.html, the main JavaScript file is not found since it is versioned based on the build.

</div><script type="text/javascript" src="/static/js/main.fa34a3ce.js"></script>

I have also tried to remove the index.html from pre-cache, and have it in the runtime cache with a network first setting. But it doesn't seem to be cached by the service worker.

runtimeCaching: [
  {
    urlPattern: /\/$/,
    handler: 'networkFirst',
    options: {
      cacheName: 'my-cache-index'
    }
  }
]
Adrian
  • 347
  • 4
  • 13
  • You may give a shot at this: https://github.com/jantimon/html-webpack-plugin. It creates the index.html from template at each build. – Ali Ankarali Apr 25 '18 at 07:52
  • Hi @AliAnkarali, appreciate the response. I forgot to say that we are using create-react-app and wouldn't want to lean into eject-ing if possible. – Adrian Apr 25 '18 at 08:07
  • You are most likely running into a common double caching situation, refer to this: [Cache Control](https://developers.google.com/web/tools/workbox/guides/service-worker-checklist#cache-control_of_your_service_worker_file) and upcoming changes in Chrome [Fresher Service Workers](https://developers.google.com/web/updates/2018/06/fresher-sw) – Dean Taylor Jun 14 '18 at 16:12
  • 1
    @DeanTaylor, this is as you have said. I was able to explore this up to the NGINX config that was serving our service-worker.js file, and upon adding the Cache-Control header into a specific the location block in our NGINX config, I was able to fix it. Thanks! – Adrian Jul 23 '18 at 13:21
  • 1
    @user3477119 I've posted by comment as an answer feel free to mark it as the answer. – Dean Taylor Jul 23 '18 at 14:57
  • How did you exclude `index.html` from precache (considering you are using create-react-app or just workbox webpack plugin)? – Finesse Nov 14 '19 at 00:44

2 Answers2

3

You are most likely running into a common double caching situation, refer to this Cache Control and upcoming changes in Chrome Fresher Service Workers.

Dean Taylor
  • 40,514
  • 3
  • 31
  • 50
0

I tried very hard to setup the network first strategy for precaching but I failed. I've gave up trying and implemented the following strategy: cache first but apply the update on a simple page reload.

To implement it, just add the following option to your Workbox service worker builder (e.g. the Webpack plugin):

skipWaiting: true

Or, if you write the service worker by yourself, add the line to your service worker code:

workbox.core.skipWaiting();

Furthermore, you can show an alert to the user when your application has been updated, and/or reload the page automatically:

// Your service worker registration code
// ...

const registration = await navigator.serviceWorker.register(serviceWorkerUrl);

registration.onupdatefound = () => {
  const installingWorker = registration.installing;
  if (installingWorker == null) {
    return;
  }
  installingWorker.onstatechange = () => {
    if (installingWorker.state === 'installed') {
      if (navigator.serviceWorker.controller) {
        if (confirm('App\'s been updated. Restart to apply the update?')) {
          location.reload();
        }
      } else {
        // The service worker has been installed for the first time
      }
    }
  };
};

By default, the update is checked when the code above is run. You can trigger a check for update manually by calling:

// An appendix to the previous code block
registration.update();

Unfortunately, there is no straightforward way to find out that there is no update.

Finesse
  • 9,793
  • 7
  • 62
  • 92