Service Worker 是浏览器与网络之间的代理层,可编程拦截请求、预缓存关键资源(如 HTML/CSS/JS)、实现离线访问;通过 install 阶段预缓存、fetch 阶段策略分流(Cache First/Network First/Stale While Revalidate)、activate 阶段版本清理,达成可控、高效、兜底的离线体验。

Service Worker 是浏览器与网络之间的代理层,能主动拦截请求、管理缓存资源,从而实现真正可控的离线访问。它不依赖 HTTP 缓存规则,而是由开发者用代码定义“哪些资源要缓、怎么缓、何时更新”,这是传统缓存做不到的。
预缓存关键静态资源
在 Service Worker 安装阶段(install),把 HTML、CSS、JS、图标等核心文件提前存入 Cache Storage。这些资源一旦缓存成功,后续即使断网也能立即加载。
- 使用 caches.open() 创建命名缓存空间,如
'static-v1' - 调用 cache.addAll() 批量添加资源路径列表,路径必须是相对当前作用域的绝对 URL(如
'/index.html') - 务必用 event.waitUntil() 包裹缓存操作,确保安装完成前缓存就绪;任一资源失败会导致整个 install 失败
运行时动态缓存策略
用户访问新页面或请求新资源时,fetch 事件触发,此时可按需决定是否缓存、从哪读取。常用策略有:
- Cache First(缓存优先):先查缓存,命中则返回;未命中再发网络请求,并将响应存入缓存(适合图片、字体、库文件)
- Network First(网络优先):先尝试网络请求,失败时 fallback 到缓存(适合 API 数据、新闻详情等时效性中等的内容)
- Stale While Revalidate(旧缓存+后台刷新):立刻返回缓存内容,同时悄悄发起网络请求更新缓存(兼顾速度与新鲜度,适合首页、列表页)
版本控制与缓存清理
每次更新 Service Worker 脚本,都会生成新版本。旧缓存若不清理,会持续占用空间,还可能造成资源错乱。
- 在 activate 阶段遍历 caches.keys(),比对当前期望的缓存名(如
'static-v2'),删除所有不匹配的旧缓存 - 配合 skipWaiting() 和 clients.claim(),让新版 Worker 立即激活并接管所有已打开页面,避免用户长时间停留在旧版本
- 缓存名建议带版本号(如
'api-data-v3'),便于精确控制生命周期
离线状态下的路由与内容兜底
单页应用(SPA)离线时,直接访问子路由(如 /article/123)可能因 HTML 未被预缓存而 404。需额外处理:
- 在 install 阶段预缓存
'/'(首页 HTML),并在 fetch 中对所有 HTML 请求 fallback 到该页面 - 对 API 请求,可缓存模拟响应(如空数组、默认文案),或展示友好的离线提示页
- 结合内存路由(如 Wouter 的
memoryLocation)或服务端重定向,确保离线导航不白屏


















