跳转到内容

Workbox

一句话: Workbox 是 Google 出品的生产级 service worker 库。它将手写的 fetch 事件逻辑替换为可组合的模块,涵盖路由、缓存策略、预缓存、后台同步和过期管理——同时保持与原生 Service Workers API 的亲近性。

模块 用途
workbox-routing 按 URL 模式或请求属性将 fetch 事件路由到不同处理器
workbox-strategies CacheFirstNetworkFirstStaleWhileRevalidateNetworkOnlyCacheOnly 的实现
workbox-precaching 基于清单的预缓存,带完整性校验和缓存清理
workbox-expiration 对任意缓存限制条目数量和 TTL
workbox-cacheable-response 按状态码或响应头过滤可缓存的响应
workbox-background-sync 将失败的 POST 请求加入队列,恢复网络后重放
workbox-broadcast-update 缓存响应更新时通知页面
workbox-google-analytics 缓存离线分析事件,恢复连接后重放
sw.js
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' })
);
Terminal window
npm install workbox-routing workbox-strategies workbox-precaching
// sw.js(打包版本)
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst } from 'workbox-strategies';
Terminal window
npm install workbox-window
import { 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 消息传递——这些原本需要在每个页面手写的样板代码。

预缓存使用构建时生成的清单来缓存一组带版本号的 URL。Workbox 追踪清单哈希,只重新获取内容发生变化的条目:

import { precacheAndRoute } from 'workbox-precaching';
// __WB_MANIFEST 由 Workbox 构建工具注入(injectManifest / generateSW)
precacheAndRoute(self.__WB_MANIFEST);

生成此清单的构建工具:workbox-webpack-plugin(通过 InjectManifestGenerateSW)、workbox-vite-pluginworkbox-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' })
);
模式 Workbox 的行为 适用场景
GenerateSW 根据你的配置生成完整的 sw.js 简单应用;worker 中无需自定义逻辑
InjectManifest 将预缓存清单注入你自己的 sw.js 模板 需要自定义路由、后台同步或预缓存以外的任何代码
  • 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 → “重新加载时更新”测试预缓存修订逻辑。