Workbox
一句话: Workbox 是 Google 出品的生产级 service worker 库。它将手写的 fetch 事件逻辑替换为可组合的模块,涵盖路由、缓存策略、预缓存、后台同步和过期管理——同时保持与原生 Service Workers API 的亲近性。
Workbox 提供了什么
Section titled “Workbox 提供了什么”| 模块 | 用途 |
|---|---|
workbox-routing |
按 URL 模式或请求属性将 fetch 事件路由到不同处理器 |
workbox-strategies |
CacheFirst、NetworkFirst、StaleWhileRevalidate、NetworkOnly、CacheOnly 的实现 |
workbox-precaching |
基于清单的预缓存,带完整性校验和缓存清理 |
workbox-expiration |
对任意缓存限制条目数量和 TTL |
workbox-cacheable-response |
按状态码或响应头过滤可缓存的响应 |
workbox-background-sync |
将失败的 POST 请求加入队列,恢复网络后重放 |
workbox-broadcast-update |
缓存响应更新时通知页面 |
workbox-google-analytics |
缓存离线分析事件,恢复连接后重放 |
CDN(无需构建工具)
Section titled “CDN(无需构建工具)”import { registerRoute } from 'https://cdn.jsdelivr.net/npm/workbox-routing@7/registerRoute.mjs';import { CacheFirst } from 'https://cdn.jsdelivr.net/npm/workbox-strategies@7/CacheFirst.mjs';
registerRoute( ({ request }) => request.destination === 'image', new CacheFirst({ cacheName: 'images' }));npm(配合打包工具)
Section titled “npm(配合打包工具)”npm install workbox-routing workbox-strategies workbox-precaching// sw.js(打包版本)import { registerRoute } from 'workbox-routing';import { CacheFirst, NetworkFirst } from 'workbox-strategies';workbox-window(在页面中使用)
Section titled “workbox-window(在页面中使用)”npm install workbox-windowimport { Workbox } from 'workbox-window';
const wb = new Workbox('/sw.js');wb.register();
// 监听更新并通知用户wb.addEventListener('waiting', () => { if (confirm('有新版本,是否刷新?')) { wb.messageSkipWaiting(); window.location.reload(); }});workbox-window 处理注册、更新检测和 skipWaiting 消息传递——这些原本需要在每个页面手写的样板代码。
使用 workbox-precaching 进行预缓存
Section titled “使用 workbox-precaching 进行预缓存”预缓存使用构建时生成的清单来缓存一组带版本号的 URL。Workbox 追踪清单哈希,只重新获取内容发生变化的条目:
import { precacheAndRoute } from 'workbox-precaching';
// __WB_MANIFEST 由 Workbox 构建工具注入(injectManifest / generateSW)precacheAndRoute(self.__WB_MANIFEST);生成此清单的构建工具:workbox-webpack-plugin(通过 InjectManifest 或 GenerateSW)、workbox-vite-plugin、workbox-cli 以及 @ducanh2912/next-pwa。
import { registerRoute, NavigationRoute } from 'workbox-routing';import { NetworkFirst, CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';import { CacheableResponsePlugin } from 'workbox-cacheable-response';import { ExpirationPlugin } from 'workbox-expiration';
// 页面(SPA 和 MPA)registerRoute( new NavigationRoute(new NetworkFirst({ cacheName: 'pages' })));
// 带过期策略的图片registerRoute( ({ request }) => request.destination === 'image', new CacheFirst({ cacheName: 'images', plugins: [ new CacheableResponsePlugin({ statuses: [200] }), new ExpirationPlugin({ maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60 }), ], }));
// 字体——旧版立即响应,长期有效registerRoute( ({ request }) => request.destination === 'font', new StaleWhileRevalidate({ cacheName: 'fonts' }));GenerateSW vs InjectManifest
Section titled “GenerateSW vs InjectManifest”| 模式 | Workbox 的行为 | 适用场景 |
|---|---|---|
GenerateSW |
根据你的配置生成完整的 sw.js |
简单应用;worker 中无需自定义逻辑 |
InjectManifest |
将预缓存清单注入你自己的 sw.js 模板 |
需要自定义路由、后台同步或预缓存以外的任何代码 |
Workbox 不覆盖的内容
Section titled “Workbox 不覆盖的内容”- Workbox 不负责生成清单或处理代码分割——那是打包工具的职责。
- 它不提供推送通知 API——请直接使用原生 Web Push API。
- Workbox 的后台同步依赖
BackgroundSyncPlugin,而该功能依赖 Background Sync API(截至本文写作时,Safari 尚不支持)。
- 将 Workbox 固定到特定主版本(
workbox-routing@7)——生产环境避免使用浮动的@latest。 - 若需要在 worker 中自定义路由或后台同步逻辑,使用
InjectManifest。 - 在页面中使用
workbox-window实现整洁的注册、更新提示和skipWaiting协调。 - 为每条
CacheFirst路由添加ExpirationPlugin,控制缓存体积增长。 - 通过 DevTools → 应用 → Service Workers → “重新加载时更新”测试预缓存修订逻辑。
- 缓存策略 — Workbox 实现的五种策略
- Fetch 事件与路由 — Workbox 所抽象的原生事件
- 更新流程与 skipWaiting —
workbox-window的messageSkipWaiting()与此相关