Skip to content

Commit

Permalink
Updates to clarify the "waiting" SW behavior (#5410)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffposnick authored and Timer committed Oct 12, 2018
1 parent 4e3ffb9 commit 5060768
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 28 deletions.
36 changes: 20 additions & 16 deletions packages/react-scripts/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1896,16 +1896,32 @@ or unreliable network.
If you do decide to opt-in to service worker registration, please take the
following into account:

1. After the initial caching is done, the [service worker lifecycle](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle)
controls when updated content ends up being shown to users. In order to guard against
[race conditions with lazy-loaded content](https://github.com/facebook/create-react-app/issues/3613#issuecomment-353467430),
the default behavior is to conservatively keep the updated service worker in the "[waiting](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting)"
state. This means that users will end up seeing older content until they close (reloading is not
enough) their existing, open tabs. See [this blog post](https://jeffy.info/2018/10/10/sw-in-c-r-a.html)
for more details about this behavior.

1. Users aren't always familiar with offline-first web apps. It can be useful to
[let the user know](https://developers.google.com/web/fundamentals/instant-and-offline/offline-ux#inform_the_user_when_the_app_is_ready_for_offline_consumption)
when the service worker has finished populating your caches (showing a "This web
app works offline!" message) and also let them know when the service worker has
fetched the latest updates that will be available the next time they load the
page (showing a "New content is available once existing tabs are closed." message). Showing
this messages is currently left as an exercise to the developer, but as a
starting point, you can make use of the logic included in [`src/serviceWorker.js`](src/serviceWorker.js), which
demonstrates which service worker lifecycle events to listen for to detect each
scenario, and which as a default, just logs appropriate messages to the
JavaScript console.

1. Service workers [require HTTPS](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers#you_need_https),
although to facilitate local testing, that policy
[does not apply to `localhost`](http://stackoverflow.com/questions/34160509/options-for-testing-service-workers-via-http/34161385#34161385).
If your production web server does not support HTTPS, then the service worker
registration will fail, but the rest of your web app will remain functional.

1. Service workers are [not supported](https://jakearchibald.github.io/isserviceworkerready/#moar)
in older web browsers. Service worker registration [won't be attempted](src/serviceWorker.js)
on browsers that lack support.

1. The service worker is only enabled in the [production environment](#deployment),
e.g. the output of `npm run build`. It's recommended that you do not enable an
offline-first service worker in a development environment, as it can lead to
Expand All @@ -1919,18 +1935,6 @@ following into account:
instructions for using other methods. _Be sure to always use an
incognito window to avoid complications with your browser cache._

1. Users aren't always familiar with offline-first web apps. It can be useful to
[let the user know](https://developers.google.com/web/fundamentals/instant-and-offline/offline-ux#inform_the_user_when_the_app_is_ready_for_offline_consumption)
when the service worker has finished populating your caches (showing a "This web
app works offline!" message) and also let them know when the service worker has
fetched the latest updates that will be available the next time they load the
page (showing a "New content is available; please refresh." message). Showing
this messages is currently left as an exercise to the developer, but as a
starting point, you can make use of the logic included in [`src/serviceWorker.js`](src/serviceWorker.js), which
demonstrates which service worker lifecycle events to listen for to detect each
scenario, and which as a default, just logs appropriate messages to the
JavaScript console.

1. By default, the generated service worker file will not intercept or cache any
cross-origin traffic, like HTTP [API requests](#integrating-with-an-api-backend),
images, or embeds loaded from a different domain.
Expand Down
28 changes: 16 additions & 12 deletions packages/react-scripts/template/src/serviceWorker.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// In production, we register a service worker to serve assets from local cache.
// This optional code is used to register a service worker.
// register() is not called by default.

// 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 the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// 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.

// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read http://bit.ly/CRA-PWA.

const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
Expand Down Expand Up @@ -41,11 +43,11 @@ export function register(config) {
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://goo.gl/SC7cgQ'
'worker. To learn more, visit http://bit.ly/CRA-PWA'
);
});
} else {
// Is not local host. Just register service worker
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
Expand All @@ -61,11 +63,13 @@ function registerValidSW(swUrl, config) {
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.
console.log('New content is available; please refresh.');
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
);

// Execute callback
if (config && config.onUpdate) {
Expand Down

0 comments on commit 5060768

Please sign in to comment.