service worker核心价值是剥离网络依赖保障可用性:预缓存带版本的html/css/js等静态资源,fetch中对navigate请求fallback至自包含离线页,按资源类型分层采用cache first、network first+fallback、stale-while-revalidate策略,activate阶段清理旧缓存并claim接管,上线前须验证https/注册时机/devtools状态。

弱网环境下,用户最需要的不是最新数据,而是“能用”。Service Worker 的核心价值,就是把“可用性”从网络依赖中剥离出来——它不保证实时,但能守住底线。
离线降级的关键逻辑:分层缓存 + 导航兜底
不能只缓存 JS/CSS,还要让页面本身可加载。关键在于两件事:
-
预缓存核心静态资源:HTML 主页、CSS、JS、图标、字体等必须在 install 阶段全部存入 Cache API,命名带版本(如
'm2lorder-v1-static'),避免缓存污染 -
拦截导航请求并返回离线页:fetch 事件中识别
request.mode === 'navigate',一旦网络失败,立刻 fallback 到已缓存的/offline.html,且该 HTML 必须自包含(内联样式/脚本,或把所有依赖路径一并加入预缓存列表)
缓存策略按资源类型动态选择
不同内容对新鲜度和速度的要求不同,混用策略才能兼顾体验与可靠性:
- Cache First:适用于 CSS、JS、图片、字体等几乎不变的资源。首次加载后,后续访问直接走缓存,零延迟
-
Network First + fallback:适用于 API 接口(如
/api/models)。先尝试网络请求,超时或失败时返回上一次缓存的响应,避免白屏或报错中断流程 - Stale-while-revalidate:适合需适度更新的内容,比如配置说明页。立即返回缓存,同时后台静默拉取新版本,下次访问即生效
激活阶段必须清理旧缓存
版本升级时,旧缓存若不清理,会导致资源错乱或离线页无法加载。在 activate 事件中做两件事:
- 调用
caches.keys()获取所有缓存名 - 过滤出非当前版本的缓存,逐个执行
caches.delete() - 加上
self.clients.claim(),确保新 SW 立即接管已有页面,避免刷新后仍走旧逻辑
上线前必须验证的三件事
很多离线功能失效,不是代码写错,而是环境或验证方式有问题:
-
HTTPS 或 localhost:Service Worker 只在 HTTPS 下生效(开发时
http://localhost是唯一例外) -
注册时机正确:必须在
window.addEventListener('load', ...)或document.readyState === 'complete'后注册,否则可能因 DOM 未就绪而失败 - DevTools 中确认状态:打开 Application → Service Workers 面板,检查是否显示 “Activated and is running”,勾选 “Update on reload” 并点击 “skipWaiting”,强制激活新版本










