First I would note that I've never used service workers nor I've attempted to make a PWA app.
I am developing an app that is expected to be used on tablets for a long period of times without closing it or using anything else. Additional requirement is to be able to add that app to a home screen.
I've read through a making-a-progressive-web-app document and there is apparently a contradiction to my use case.
If I enable service worker I should be able to get "add to home screen" prompt which is great. Unfortunately, if I understand it correctly, the app won't be updated until force killed. That's not a great UX really. We have like hundreds of clients using this and it's a nonsense to email them "kill the app".
What I would basically like to see is some in-app popup that there is an update to the app and they need to restart it. I am not sure if it's possible to restart a mobile app using Javascript. That would be even better :)
So I am wondering what are my options here. I assume it's mostly about writing my own custom service worker, but it feels so overwhelming at this moment. I could use some basic pointers.
It sounds like you need to set skipWaiting: true, AFAIK. I'll /cc @jeffposnick for more insight.
We're about to merge a PR that will allow this.
A service worker is updated when there's a navigation request made to a URL in the service worker's scope:
https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#updates
skipWaiting is relevant for situations in which there are multiple tabs open, each with pages under your service worker's scope鈥攚hen skipWaiting is false (the default in c-r-a v2), the updated precached resources won't be used until all of the tabs have closed.
If you expect that users will primarily interact with your web app via the add-to-homescreen experience, then you're less likely to run into delayed updates due to skipWaiting being disabled, since you're (presumably) not going to have multiple instances of your web app running at the same time.
@jeffposnick Thank you for the answer. I will give a try, it sounds like it should work just fine. I am curious thou if it will somehow magically update the whole app or do I need to force reload? Given that I am using code splitting, it's hard to imagine it would do something similar to hot reloading :)
So I am assuming I should use onSuccess callback through register(config) and notify a user that there is a new update and reload app upon hitting the button.
The current behavior, where skipWaiting is disabled, is specifically in place to prevent problems due to lazy-loading. (See https://jeffy.info/2018/10/10/sw-in-c-r-a.html for some rough thoughts.)
The new set of versioned assets will only be considered "active" once all the existing clients using the previous version have closed / navigated to a new document. (And by "navigated", I'm referring to an actual navigation request that results in the DOM being unloaded, not a SPA-style navigation using the History API.)
There's a PR open from @arackaf that gives a pretty complete example of how/when to message this to users: https://github.com/facebook/create-react-app/pull/5491
Ok, so I've been fiddling with this for a couple of hours now, mainly with information from #5491 and I think I understand basics now. It certainly has some nice flavor to it, but it seems there is still an unsolved issue regarding the long-running app approach.
When service worker is up and running and a new version of the app is deployed, it seems it won't notice it on its own. I mean how could it? It's just static content that suddenly appeared on the network. Is there some hidden periodical check for that content which I haven't noticed?
I am able to notify a user about a new version and offer update + reload, but only after the user reloads app on his own first. Not only the user does not know he needs to refresh, but the app is running in the full screen on tablet, so there won't even be any means of manually reloading.
Unless there is something I am missing in this regard, I guess I'll have to implement some sort of backend micro service that can report what version is deployed to notify a client. However, it feels weird anyway, as a user will have to reload once to get an update and then again to apply an update. I hope there is a better way :(
Ok, sorry for bothering you, this was the piece of information I've been missing.

I just need to figure best scenario when to run that update, but that's out of the scope of CRA.
In case if someone wonders how to get access to reg object, it's simply as const reg = await navigator.serviceWorker.getRegistration()
Most helpful comment
The current behavior, where
skipWaitingis disabled, is specifically in place to prevent problems due to lazy-loading. (See https://jeffy.info/2018/10/10/sw-in-c-r-a.html for some rough thoughts.)The new set of versioned assets will only be considered "active" once all the existing clients using the previous version have closed / navigated to a new document. (And by "navigated", I'm referring to an actual navigation request that results in the DOM being unloaded, not a SPA-style navigation using the History API.)
There's a PR open from @arackaf that gives a pretty complete example of how/when to message this to users: https://github.com/facebook/create-react-app/pull/5491