mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-05-22 20:37:51 +08:00
110 lines
7.2 KiB
Markdown
110 lines
7.2 KiB
Markdown
---
|
|
id: making-a-progressive-web-app
|
|
title: Making a Progressive Web App
|
|
---
|
|
|
|
The production build has all the tools necessary to generate a first-class
|
|
[Progressive Web App](https://developers.google.com/web/progressive-web-apps/),
|
|
but **the offline/cache-first behavior is opt-in only**. By default,
|
|
the build process will generate a service worker file, but it will not be
|
|
registered, so it will not take control of your production web app.
|
|
|
|
In order to opt-in to the offline-first behavior, developers should look for the
|
|
following in their [`src/index.js`](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/src/index.js) file:
|
|
|
|
```js
|
|
// If you want your app to work offline and load faster, you can change
|
|
// unregister() to register() below. Note this comes with some pitfalls.
|
|
// Learn more about service workers: http://bit.ly/CRA-PWA
|
|
serviceWorker.unregister();
|
|
```
|
|
|
|
As the comment states, switching `serviceWorker.unregister()` to
|
|
`serviceWorker.register()` will opt you in to using the service worker.
|
|
|
|
## Why Opt-in?
|
|
|
|
Offline-first Progressive Web Apps are faster and more reliable than traditional web pages, and provide an engaging mobile experience:
|
|
|
|
- All static site assets are cached so that your page loads fast on subsequent visits, regardless of network connectivity (such as 2G or 3G). Updates are downloaded in the background.
|
|
- Your app will work regardless of network state, even if offline. This means your users will be able to use your app at 10,000 feet and on the subway.
|
|
- On mobile devices, your app can be added directly to the user's home screen, app icon and all. This eliminates the need for the app store.
|
|
|
|
However, they [can make debugging deployments more challenging](https://github.com/facebook/create-react-app/issues/2398) so, starting with Create React App 2, service workers are opt-in.
|
|
|
|
The [`workbox-webpack-plugin`](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin)
|
|
is integrated into production configuration,
|
|
and it will take care of generating a service worker file that will automatically
|
|
precache all of your local assets and keep them up to date as you deploy updates.
|
|
The service worker will use a [cache-first strategy](https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network)
|
|
for handling all requests for local assets, including
|
|
[navigation requests](https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests)
|
|
for your HTML, ensuring that your web app is consistently fast, even on a slow
|
|
or unreliable network.
|
|
|
|
## Offline-First Considerations
|
|
|
|
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
|
|
these 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`](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/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. The service worker is only enabled in the [production environment](deployment.md),
|
|
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
|
|
frustration when previously cached assets are used and do not include the latest
|
|
changes you've made locally.
|
|
|
|
1. If you _need_ to test your offline-first service worker locally, build
|
|
the application (using `npm run build`) and run a simple http server from your
|
|
build directory. After running the build script, `create-react-app` will give
|
|
instructions for one way to test your production build locally and the [deployment instructions](deployment.md) have
|
|
instructions for using other methods. _Be sure to always use an
|
|
incognito window to avoid complications with your browser cache._
|
|
|
|
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.md),
|
|
images, or embeds loaded from a different domain.
|
|
|
|
## Progressive Web App Metadata
|
|
|
|
The default configuration includes a web app manifest located at
|
|
[`public/manifest.json`](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/public/manifest.json), that you can customize with
|
|
details specific to your web application.
|
|
|
|
When a user adds a web app to their homescreen using Chrome or Firefox on
|
|
Android, the metadata in [`manifest.json`](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/public/manifest.json) determines what
|
|
icons, names, and branding colors to use when the web app is displayed.
|
|
[The Web App Manifest guide](https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/)
|
|
provides more context about what each field means, and how your customizations
|
|
will affect your users' experience.
|
|
|
|
Progressive web apps that have been added to the homescreen will load faster and
|
|
work offline when there's an active service worker. That being said, the
|
|
metadata from the web app manifest will still be used regardless of whether or
|
|
not you opt-in to service worker registration.
|