Service Worker Causing a Blank Page After Refresh in React Application

Viewed 3253

I have a Node application deployed to Azure, with a test branch leading to a staging instance, and a master branch pointed at the prod deployment. My application works fine on all instances of the application locally, but production and staging are having an issue in which they will not load if they are already cached, and will appear blank after a refresh, and lastly will work properly with a cache reset.

Whenever I refresh the page in production, it is just blank. The service worker is running (I can see it in the chrome serviceworkers-internal tool), but the page just never loads. The file references generated are correct. You can see an example of what is happening here: Live Site and then you can also see the testing site which is also failing with the exact same code deployed: Test Site.

The entirety of the ServiceWorker implementation is out of the box from create-react-app. I've spent several hours trying to track this bug down across a variety of GitHub issues under the react-boilerplate and create-react-app repos and none of them really get anywhere beyond restricting page caching, which I tried to do with no avail with:

Index.html

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0"/>

You can find any of the code you have questions about any code at the repo that hosts all of this code.

I'm just kind of getting my feet wet with React/Node, so I'm at a wall and don't really see how to get around this without completely ripping out the ServiceWorker registration.

EDIT: I completely removed the ServiceWorker code from the index.js file and the sight reloads without any issues now. Is there a step I need to complete to get the ServiceWorker to properly reload the page from cache or something?

2 Answers

In case someone else finds this question like me, the answer was to disable browser cache on the service worker file (service-worker.js for me) and index.html, and cache forever the rest.

It appears when a change is made the old version of the app continues to run, and on startup it then detects there is a new version. If like me you don't cache the static resources then when it tries to fetch the old version it gets a 404 resulting in a blank page. If you refresh a second time it gets the new version of the app.

I added some code into mine to automatically reload after 5 seconds by modifying registerServiceWorker.js

function registerValidSW(swUrl) {
console.debug('Registering serviceWorker URL [' + swUrl + ']');
navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
        registration.onupdatefound = () => {
            const installingWorker = registration.installing;
            installingWorker.onstatechange = () => {
                if (installingWorker.state === 'installed') {
                    if (navigator.serviceWorker.controller) {
                        // At this point, the old content will have been purged and
                        // the fresh content will have been added to the cache.
                        // It's the perfect time to display a "New content is
                        // available; please refresh." message in your web app.
                        reportInfo('App has been updated. This page will refresh in 5 seconds.');
                        setInterval(()=>window.location.reload(), 5000);
                    } else {
                        // At this point, everything has been precached.
                        // It's the perfect time to display a
                        // "Content is cached for offline use." message.
                        reportInfo('App is cached for offline use.');
                    }
                }
            };
        };
    })
    .catch(error => {
        reportError('Error during service worker registration:', error);
    });

}

For anyone having the same issue as me using react and react-router-dom for a single page application, I had only a blank page on my installed application after calling window.location.reload() (on an android One Plus) because I was not redirecting from my route '/user' to the home '/' or '/index.html' on my server

If you have a single page application, please see this awnser for different ways to fix it: https://stackoverflow.com/a/36623117/17434198

Related