I only had to modify a few files to achieve my desired behavior. The hard part, for me at least, was developing a technical understanding of what a service worker does, and then developing a commensurate understanding of how Google Workbox is trying to simplify how you work with them. With regard to the former, I found this documentation from Mozilla the most informative, “MDN Web Docs: Service Worker API“. Learning about Workbox on the other hand is more of a challenge. I ended up tracing the source code.
Service Workers are are powerful. The scaffolding that you get from create-react-app really only scratches the surface. Having said that, there are weird gaps in the Service Worker API. For example, there are events for ‘fetch’ and ‘install’ and ‘activate’ but not for ‘fetched’ and ‘installed’ and ‘activated’, even though there are defined states for these.
The service worker life cycle model is simple. A service worker has four possible states, which migrate as follows: installing, then installed, then activating, then activated. There’s also a general purpose exception state called redundant. The built-in wait period between ‘installed’ and ‘activating’ can be overriden by calling skipwaiting() (see an example of this in the default service-worker.js. You should note a couple of things however. First, it is recommended that your React app communicate with the service worker via a formal postMessage() api. And second, that regardless of how you call skipwaiting(), it will only have an effect if there is actually a installed worker in an ‘installed’ state.
Debugging service workers is a challenge. For one thing, they only run on your “production” build, which obviously complicates testing. But additionally, the very nature of service workers is that they directly control what version of your code you’re running, and that can get confusing. Lastly, its all event-driven which itself is challenging to trace and debug. My advise is to make copious use of console logging, as per the video screen cast above, so that execution threads are abundantly clear.