在构建可靠的 Web 应用时,有两个 API 发挥着至关重要的作用:Service Worker 和 Cache Storage。但是,要想有效地使用它们(而不引入细微的 bug 或遇到极端情况),这可能并非易事。例如,服务工件代码中的错误可能会导致缓存问题;用户可能会看到过时的内容或损坏的链接。
Workbox 是一个高级 Service Worker 工具包,基于 Service Worker 和 Cache Storage API 构建而成。它提供了一组可用于向 Web 应用添加离线支持的正式版库。该工具包分为两个集合:用于帮助管理在服务工件中运行的代码的工具,以及与 build 流程集成的工具。
运行时代码
这是在您的服务工件脚本中运行的代码,用于控制它如何拦截传出请求并与 Cache Storage API 交互。Workbox 总共有十几个库模块,每个模块都处理各种专用用例。最重要的模块决定了服务工件是否会响应(称为“路由”),以及响应方式(称为“缓存策略”)。
构建集成
Workbox 提供了命令行、Node.js 模块和 webpack 插件工具,可通过其他方式实现以下两项:
- 根据一组配置选项创建服务工件脚本。生成的服务工件会“在后台”使用 Workbox 的运行时库来实现您配置的缓存策略。
- 根据可配置的模式生成应“预缓存”的网址列表,以包含和排除构建过程中生成的文件。
为什么应使用 Workbox?
在构建服务工作器时使用 Workbox 并非强制性要求,您可以查看一些指南,从“常规”服务工作器的角度了解常见的缓存策略。如果您决定使用 Workbox,请参考以下一些优势。
缓存管理
Workbox 会为您处理缓存更新,在使用预缓存时,会与构建流程相关联;在使用运行时缓存时,则会通过可配置的大小/年龄政策进行处理。底层 Cache Storage API 功能强大,但不支持任何内置缓存过期功能。Workbox 等工具填补了这一空白。
详尽的日志记录和错误报告
刚开始使用服务工件时,您可能会发现很难确定某项内容为何被缓存(或者同样令人沮丧的是,为何未缓存)。Workbox 会自动检测您何时在 localhost
上运行网站的开发版本,并在浏览器的 JavaScript 控制台中开启调试日志记录。
与单独处理相比,通过跟踪日志消息,您可以更快地找到任何配置或失效问题的根本原因。
经过测试的跨浏览器代码库
Workbox 是根据跨浏览器测试套件开发的,并会在可能的情况下自动回退到某些浏览器缺少的功能的替代实现。
workbox-broadcast-cache-update module
会在可用时使用 Broadcast Channel API,并在缺少支持的浏览器上回退到基于postMessage()
的实现。- workbox-background-sync 模块会尽可能使用 Background Sync API,如果无法使用,则会在每次服务工件启动时回退到重试队列中的事件。
如何使用 Workbox?
框架集成
如果您要从头开始创建一个新项目,可以利用许多热门入门套件和插件中提供的 Workbox 集成:
将 Workbox 添加到现有构建流程
如果您已经为自己的网站建立了构建流程,那么只需添加适当的命令行、Node.js 模块或 webpack 插件工具,即可开始使用 Workbox。
特别是,Workbox 命令行界面可让您轻松上手,其 wizard
模式会检查您的本地开发环境,并建议您在今后可以使用的合理默认配置:
workbox wizard
? What is the root of your web app (i.e. which directory do you deploy)? src/
? Which file types would you like to precache? css, js, html
? Where would you like your service worker file to be saved? build/sw.js
? Where would you like to save these configuration options? workbox-config.js
如需构建服务工作器,请在构建过程中运行 workbox generateSW workbox-config.js
。如需了解详情,请参阅 generateSW
文档。您可以通过更改 workbox-config.js
进一步自定义 Service Worker。如需了解详情,请参阅选项文档。
在现有 Service Worker 中运行时使用 Workbox
如果您已有服务工件,并希望试用 Workbox 的运行时库,请从其官方 CDN 导入 Workbox,并立即开始将其用于运行时缓存。这种用例意味着您无法利用预缓存(需要在构建时进行集成),但非常适合快速原型设计和试用不同的缓存策略。
// Replace 3.6.3 with the current version number of Workbox.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js');
workbox.routing.registerRoute(
new RegExp('\.png$'),
workbox.strategies.cacheFirst({
cacheName: 'images-cache',
})
);