Service Worker 离线缓存实战:从可安装到弱网可用
静态预缓存、运行时缓存、版本更新与回滚、iOS 与安卓差异处理,一份能直接抄的 PWA 缓存策略。
PWA 的价值不只是「能装到桌面」,更重要的是在弱网、断网、地铁、电梯里依然能打开。要做到这一点,核心是把缓存策略设计清楚:什么预缓存、什么运行时缓存、什么时候失效。
一、静态预缓存(Precache)
在 install 阶段把应用外壳(HTML 骨架、CSS、关键 JS、图标、离线兜底页)写入 Cache Storage。只缓存真正必要的资源,别把整站一股脑塞进去——首装体积直接影响安装成功率。
二、运行时缓存:按资源类型分流
不同资源用不同策略:静态资源用 stale-while-revalidate(先快后新);接口数据用 network-first(优先新鲜,失败回落缓存);图片用 cache-first + 数量上限,避免撑爆配额。
- HTML 外壳:network-first,失败回落预缓存
- 带 hash 的静态资源:cache-first(内容寻址天然可永久缓存)
- 只读接口:stale-while-revalidate
- 写操作:永不缓存,且失败要入队重试
三、版本更新与原子回滚
每次发版递增缓存版本号,activate 阶段清理旧缓存;新版本在 waiting 态时通过 skipWaiting + 提示用户刷新完成接管。务必保留上一版预缓存作为回滚落点,出问题时能一键退回。
四、iOS 与安卓的差异
iOS 上需要 apple-mobile-web-app-capable、apple-touch-icon 与状态栏配色 meta;后台清理策略更激进,缓存配额更保守。安卓需处理安装横幅与更新提示。两端都要真机回归,模拟器测不出来。
五、可观测与常见坑
记录缓存命中率、离线打开成功率与更新失败率三个指标。最常见的三个坑:缓存了带 Set-Cookie 的响应、把错误页缓存下来、以及忘记在更新后清理旧版本导致混合态。
- 不要缓存个性化/带凭证的响应
- 只缓存 2xx 与 basic 类型响应
- 更新后立即清理旧缓存并上报版本号
缓存策略没有银弹,但有下限:保证外壳秒开、保证写操作不丢、保证能回滚。做到这三点,离线体验就已经超过大多数同类站点。
把 QSTAR 装到桌面,弱网也能继续用