Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service Worker Causing a Blank Page After Refresh in React Application

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?

like image 690
Robert McCoy Avatar asked Sep 30 '17 08:09

Robert McCoy


People also ask

How to use service workers in ReactJS?

To register the service worker, navigate to the src/index.js file, and look for the following line: Change it to the following line. This single line change will now enable you to use service workers in your React application. In a general web application, you would have to code the whole lifecycle of a service worker.

How to refresh a page in react?

The second, and more appropriate method of refreshing a page in React, is to update the state inside of the React component. React is a modern JavaScript library and therefore does not require a page refresh to display the latest data in the UI. A really common example of refreshing a page when the UI needs to be updated is an e-commerce site.

How to fix a white screen after deploying a react app?

The next time you get a white screen after deploying a React app, remember the steps you’ve learned today: 1 Check the browser’s console for errors 2 Does the app link to the wrong bundle? 3 Update the “homepage” setting in your package.json 4 Build your app again and put it on your web space 5 Success! More ...

What is the lifecycle of a service worker in react?

The lifecycle of a service worker typically needs to be coded by the developer. In case of service workers in React, the life cycle management is handled by React itself, which makes the process easier for a developer to enable and use service workers.


1 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);
    });

}

like image 165
Iain Avatar answered Nov 15 '22 21:11

Iain