跳至主要内容

创建渐进式 Web 应用

生产构建包含生成一流 渐进式 Web 应用 的所有必要工具,但离线/缓存优先行为仅为可选

从 Create React App 4 开始,您可以向项目中添加一个 src/service-worker.js 文件来使用对 Workbox 的内置支持,该支持的 InjectManifest 插件将 编译 您的服务工作者并向其中注入要 预缓存 的 URL 列表。

如果您使用其中一个 PWA 自定义模板 启动新项目,您将获得一个 src/service-worker.js 文件,该文件作为离线优先服务工作者的良好起点。

npx create-react-app my-app --template cra-template-pwa

TypeScript 等效代码为

npx create-react-app my-app --template cra-template-pwa-typescript

如果您知道不会使用服务工作者,或者您更喜欢使用其他方法创建服务工作者,请不要创建 src/service-worker.js 文件。在这种情况下,InjectManifest 插件不会运行。

除了创建本地 src/service-worker.js 文件外,还需要在使用之前注册它。为了选择加入离线优先行为,开发人员应该在他们的 src/index.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: https://cra.link/PWA
serviceWorkerRegistration.unregister();

如注释所述,将 serviceWorker.unregister() 切换为 serviceWorker.register() 将使您选择加入使用服务工作者。

为什么要选择加入?

离线优先的渐进式 Web 应用程序比传统的网页更快、更可靠,并提供引人入胜的移动体验

  • 所有作为 webpack 构建一部分的静态站点资产都已缓存,以便您的页面在后续访问中快速加载,无论网络连接如何(例如 2G 或 3G)。更新将在后台下载。
  • 无论网络状态如何,您的应用程序都能正常工作,即使离线也是如此。这意味着您的用户可以在 10,000 英尺高空和地铁上使用您的应用程序。
  • 在移动设备上,您的应用程序可以直接添加到用户的主屏幕,包括应用程序图标。这消除了对应用商店的需求。

但是,它们 可能会使调试部署更具挑战性

workbox-webpack-plugin 集成到生产配置中,它将负责编译一个服务工作者文件,该文件将自动预缓存所有 webpack 生成的资产,并在您部署更新时保持最新。服务工作者将使用 缓存优先策略 处理所有对 webpack 生成的资产的请求,包括 导航请求 用于您的 HTML,确保您的 Web 应用程序始终快速,即使在缓慢或不可靠的网络上也是如此。

注意:不是由 webpack 生成的资源,例如从本地 public/ 目录 复制过来的静态文件或第三方资源,不会被预缓存。您可以选择设置 Workbox 路由 以将您选择的运行时缓存策略应用于这些资源。

自定义

从 Create React App 4 开始,您可以完全控制此服务工作者的逻辑自定义,方法是创建您自己的 src/service-worker.js 文件,或自定义由 cra-template-pwa(或 cra-template-pwa-typescript)模板添加的文件。您可以使用来自 Workbox 项目的 附加模块,添加推送通知库,或删除一些默认的缓存逻辑。唯一的要求是您在文件中保留 self.__WB_MANIFEST,因为 Workbox 编译插件在生成要预缓存的 URL 清单时会检查此值。如果您不想使用预缓存,可以将 self.__WB_MANIFEST 分配给一个将被忽略的变量,例如

// eslint-disable-next-line no-restricted-globals
const ignored = self.__WB_MANIFEST;

// Your custom service worker code goes here.

离线优先注意事项

如果您决定选择加入服务工作者注册,请考虑以下事项

  1. 完成初始缓存后,服务工作者生命周期 控制更新的内容何时最终显示给用户。为了防止 与延迟加载内容的竞争条件,默认行为是保守地将更新的服务工作者保留在“等待”状态。这意味着用户最终将看到旧内容,直到他们关闭(重新加载是不够的)他们现有的打开的选项卡。有关此行为的更多详细信息,请参阅 这篇博文

  2. 用户并不总是熟悉离线优先的 Web 应用程序。可以 让用户知道 服务工作者何时完成填充缓存(显示“此 Web 应用程序可在离线状态下使用!”消息),以及让他们知道服务工作者何时获取了下次加载页面时可用的最新更新(显示“新内容在关闭现有选项卡后可用。”消息)。显示这些消息目前留给开发人员自行决定,但作为起点,您可以使用 src/serviceWorkerRegistration.js 中包含的逻辑,该逻辑演示了要监听哪些服务工作者生命周期事件以检测每种情况,以及默认情况下,仅将适当的消息记录到 JavaScript 控制台。

  3. 服务工作者 需要 HTTPS,尽管为了便于本地测试,该策略 不适用于 localhost。如果您的生产 Web 服务器不支持 HTTPS,则服务工作者注册将失败,但您的 Web 应用程序的其余部分将保持功能。

  4. 服务工作者仅在 生产环境 中启用,例如 npm run build 的输出。建议您不要在开发环境中启用离线优先服务工作者,因为它会导致您之前缓存的资产被使用且不包含您在本地所做的最新更改,从而导致沮丧。

  5. 如果您需要在本地测试您的离线优先服务工作者,请构建应用程序(使用 npm run build)并从您的构建目录运行一个标准的 http 服务器。在运行构建脚本后,create-react-app 将提供在本地测试生产构建的一种方法的说明,以及 部署说明 中有关使用其他方法的说明。请务必始终使用隐身窗口以避免与浏览器缓存发生冲突。

  6. 默认情况下,生成的 service worker 文件不会拦截或缓存任何跨域流量,例如来自不同域的 HTTP API 请求、图像或嵌入。从 Create React App 4 开始,可以根据上述说明进行自定义。

渐进式 Web 应用程序元数据

默认配置包括一个位于 public/manifest.json 的 Web 应用程序清单,您可以使用特定于您的 Web 应用程序的详细信息对其进行自定义。

当用户使用 Android 上的 Chrome 或 Firefox 将 Web 应用程序添加到其主屏幕时,manifest.json 中的元数据将决定在显示 Web 应用程序时使用哪些图标、名称和品牌颜色。 Web 应用程序清单指南 提供了有关每个字段含义以及您的自定义将如何影响用户体验的更多信息。

已添加到主屏幕的渐进式 Web 应用程序将在有活动服务工作者时加载更快并在脱机时工作。话虽如此,Web 应用程序清单中的元数据仍将被使用,无论您是否选择加入服务工作者注册。