Network first caching of index.html using workbox.js
Asked Answered
S

2

13

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'
    }
  }
]
Spermatogonium answered 25/4, 2018 at 7:46 Comment(6)
You may give a shot at this: github.com/jantimon/html-webpack-plugin. It creates the index.html from template at each build.Troth
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.Spermatogonium
You are most likely running into a common double caching situation, refer to this: Cache Control and upcoming changes in Chrome Fresher Service WorkersHalflight
@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!Spermatogonium
@user3477119 I've posted by comment as an answer feel free to mark it as the answer.Halflight
How did you exclude index.html from precache (considering you are using create-react-app or just workbox webpack plugin)?Schechinger
H
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.

Halflight answered 23/7, 2018 at 14:56 Comment(0)
S
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.

Schechinger answered 4/12, 2019 at 3:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.