Search code examples
javascriptreactjsservice-workercreate-react-app

Routes being cached by service worker in react


We are in the process of building a new website for the company I work for which is written in React using CRA. Browser push notifications and a PWA are both required so a service worker is essential, however I beleive the service worker is responsible for some fairly major caching issues.

The website is not yet in production however I added a new page yesterday (and this has happened a few times before) and once deployed to our dev environment nobody in the office was able to access it - they were simply redirected to the homepage (as if the route didn't exist) until they cleared their cache then the route loaded with no issues.

I've read a little bit on semantic versioning however the articles all seem to use NPM rather than yarn and are versioned locally (which isn't great with a team of 8 working on this project) using npm version patch etc.

We are using MS Azure as the build and release pipeline which I assume would be the best place to set versions if this is required.

My question is what are the steps to aviod this problem and am I on the correct lines thinking versioning will mitigate?


Solution

  • Semantic versioning in this context doesn't make any sense, you've been reading most likely about packages (libraries, frameworks) that are published into NPM for the world to use. In CRA projects, and most other web projects too, versioning of your app happens by the build tools as they name the files based on their contents. The filenames include the hash of the contents and are versioned automatically when contents change, eg. app.iue9234980s.js becomes app.92384oujiuoisdf.js etc.

    --

    If you're using the default Service Worker setup provided by CRA, then you should look at src/serviceWorker.js. In the comments of that file it says

    // This lets the app load faster on subsequent visits in production, and gives
    // it offline capabilities. However, it also means that developers (and users)
    // will only see deployed updates on subsequent visits to a page, after all the
    // existing tabs open on the page have been closed, since previously cached
    // resources are updated in the background.
    

    What happens here is that the SW and the build process use Workbox SW library that is configured to use precache policy. In this policy, users get the last version that was previously cached from the browser's cache even if there's a new version available, then in the background SW updates the caches, and on another visit users get the newer version. This of course means that users might always be one version "late".

    If this behaviour is not what you want, then you need to change src/serviceWorker.js and probably some configuration somewhere in CRA files. You should google something like "custom service workers with cra" for examples.

    To better grasp what is happening – and especially what is correct and intended behaviour in differently configured cases – I really recommend (everyone) to read Google's primer on SWs themselves, here: https://developers.google.com/web/fundamentals/primers/service-workers With understanding of the SWs basic principles, it is then probably useful to checkout the Workbox library https://developers.google.com/web/tools/workbox to see what it can offer for your app.

    Reading and understanding the different aspects of SW is key here – it is excruciatinly easy to shoot yourself in the foot with SWs :)