Skip to content

Commit a6488d6

Browse files
jeffposnickTimer
authored andcommitted
Updates to clarify the "waiting" SW behavior (facebook#5410)
1 parent d5dcb70 commit a6488d6

File tree

2 files changed

+36
-28
lines changed

2 files changed

+36
-28
lines changed

template/README.md

+20-16
Original file line numberDiff line numberDiff line change
@@ -1896,16 +1896,32 @@ or unreliable network.
18961896
If you do decide to opt-in to service worker registration, please take the
18971897
following into account:
18981898

1899+
1. After the initial caching is done, the [service worker lifecycle](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle)
1900+
controls when updated content ends up being shown to users. In order to guard against
1901+
[race conditions with lazy-loaded content](https://github.com/facebook/create-react-app/issues/3613#issuecomment-353467430),
1902+
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)"
1903+
state. This means that users will end up seeing older content until they close (reloading is not
1904+
enough) their existing, open tabs. See [this blog post](https://jeffy.info/2018/10/10/sw-in-c-r-a.html)
1905+
for more details about this behavior.
1906+
1907+
1. Users aren't always familiar with offline-first web apps. It can be useful to
1908+
[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)
1909+
when the service worker has finished populating your caches (showing a "This web
1910+
app works offline!" message) and also let them know when the service worker has
1911+
fetched the latest updates that will be available the next time they load the
1912+
page (showing a "New content is available once existing tabs are closed." message). Showing
1913+
this messages is currently left as an exercise to the developer, but as a
1914+
starting point, you can make use of the logic included in [`src/serviceWorker.js`](src/serviceWorker.js), which
1915+
demonstrates which service worker lifecycle events to listen for to detect each
1916+
scenario, and which as a default, just logs appropriate messages to the
1917+
JavaScript console.
1918+
18991919
1. Service workers [require HTTPS](https://developers.google.com/web/fundamentals/getting-started/primers/service-workers#you_need_https),
19001920
although to facilitate local testing, that policy
19011921
[does not apply to `localhost`](http://stackoverflow.com/questions/34160509/options-for-testing-service-workers-via-http/34161385#34161385).
19021922
If your production web server does not support HTTPS, then the service worker
19031923
registration will fail, but the rest of your web app will remain functional.
19041924

1905-
1. Service workers are [not supported](https://jakearchibald.github.io/isserviceworkerready/#moar)
1906-
in older web browsers. Service worker registration [won't be attempted](src/serviceWorker.js)
1907-
on browsers that lack support.
1908-
19091925
1. The service worker is only enabled in the [production environment](#deployment),
19101926
e.g. the output of `npm run build`. It's recommended that you do not enable an
19111927
offline-first service worker in a development environment, as it can lead to
@@ -1919,18 +1935,6 @@ following into account:
19191935
instructions for using other methods. _Be sure to always use an
19201936
incognito window to avoid complications with your browser cache._
19211937

1922-
1. Users aren't always familiar with offline-first web apps. It can be useful to
1923-
[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)
1924-
when the service worker has finished populating your caches (showing a "This web
1925-
app works offline!" message) and also let them know when the service worker has
1926-
fetched the latest updates that will be available the next time they load the
1927-
page (showing a "New content is available; please refresh." message). Showing
1928-
this messages is currently left as an exercise to the developer, but as a
1929-
starting point, you can make use of the logic included in [`src/serviceWorker.js`](src/serviceWorker.js), which
1930-
demonstrates which service worker lifecycle events to listen for to detect each
1931-
scenario, and which as a default, just logs appropriate messages to the
1932-
JavaScript console.
1933-
19341938
1. By default, the generated service worker file will not intercept or cache any
19351939
cross-origin traffic, like HTTP [API requests](#integrating-with-an-api-backend),
19361940
images, or embeds loaded from a different domain.

template/src/serviceWorker.js

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
// In production, we register a service worker to serve assets from local cache.
1+
// This optional code is used to register a service worker.
2+
// register() is not called by default.
23

34
// This lets the app load faster on subsequent visits in production, and gives
45
// it offline capabilities. However, it also means that developers (and users)
5-
// will only see deployed updates on the "N+1" visit to a page, since previously
6-
// cached resources are updated in the background.
6+
// will only see deployed updates on subsequent visits to a page, after all the
7+
// existing tabs open on the page have been closed, since previously cached
8+
// resources are updated in the background.
79

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

1113
const isLocalhost = Boolean(
1214
window.location.hostname === 'localhost' ||
@@ -41,11 +43,11 @@ export function register(config) {
4143
navigator.serviceWorker.ready.then(() => {
4244
console.log(
4345
'This web app is being served cache-first by a service ' +
44-
'worker. To learn more, visit https://goo.gl/SC7cgQ'
46+
'worker. To learn more, visit http://bit.ly/CRA-PWA'
4547
);
4648
});
4749
} else {
48-
// Is not local host. Just register service worker
50+
// Is not localhost. Just register service worker
4951
registerValidSW(swUrl, config);
5052
}
5153
});
@@ -61,11 +63,13 @@ function registerValidSW(swUrl, config) {
6163
installingWorker.onstatechange = () => {
6264
if (installingWorker.state === 'installed') {
6365
if (navigator.serviceWorker.controller) {
64-
// At this point, the old content will have been purged and
65-
// the fresh content will have been added to the cache.
66-
// It's the perfect time to display a "New content is
67-
// available; please refresh." message in your web app.
68-
console.log('New content is available; please refresh.');
66+
// At this point, the updated precached content has been fetched,
67+
// but the previous service worker will still serve the older
68+
// content until all client tabs are closed.
69+
console.log(
70+
'New content is available and will be used when all ' +
71+
'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
72+
);
6973

7074
// Execute callback
7175
if (config && config.onUpdate) {

0 commit comments

Comments
 (0)