Service Worker 的降级策略需主动适配存储限制:检测 Cache API 和 IndexedDB 可用性,动态切换缓存策略;IndexedDB 不可用时改用 sessionStorage 或内存暂存;离线体验聚焦预缓存核心资源与本地 fallback 内容。

Service Worker 本身不直接涉及“存储 API 权限”,但它的核心能力(如缓存、拦截请求、离线运行)高度依赖 Cache API 和 IndexedDB。当这些底层存储接口因浏览器策略、用户设置或运行环境受限(例如隐私模式、企业策略禁用、iOS Safari 的严格限制)而不可用或容量被强制压缩时,PWA 就会降级为“无缓存”或“仅基础功能”。真正的降级降容,不是绕过限制,而是主动适配限制。
识别存储能力是否受限
不能假设 Cache API 或 IndexedDB 一定可用。需在注册 Service Worker 前/中做细粒度检测:
- 用
caches.open()+.then()+.catch()检查 Cache API 是否可写(部分 iOS Safari 私密窗口会拒绝打开缓存) - 用
window.indexedDB.open()并监听onblocked/onupgradeneeded异常,判断 IndexedDB 是否被禁用或配额耗尽 - 对 Safari(尤其是 iOS),额外检查
navigator.storage.estimate()返回的quota是否接近零——这代表系统已主动降容
缓存层动态降级:从 Cache First 到 Network Only
当缓存不可用时,应避免让 fetch 事件处理器崩溃,而是切换至安全兜底逻辑:
- 在
fetch事件中,先尝试caches.match(req);若 Promise 被 reject(非未命中,而是权限错误),立即 fallback 到fetch(req) - 不使用
Cache First策略,改用Network Falling Back to Cache的变体:只在缓存可用时才读,否则直连网络,不报错也不阻塞 - 对关键静态资源(如 logo、主样式表),预设一个最小化内联 fallback:在 HTML 中用
<link rel="stylesheet" href="/fallback.css" onerror="this.href='/minimal.css'">
IndexedDB 降容:精简结构 + 内存暂存替代
当 IndexedDB 被禁用或写入失败,不要丢弃数据,而是用轻量级替代方案维持基本状态:
- 将原本存入 IndexedDB 的非敏感临时状态(如表单草稿、UI 展开状态)转为
sessionStorage或localStorage(注意它们也有配额,但更宽松) - 对必须持久化的少量核心数据(如用户偏好),采用“内存优先 + 定时快照”策略:先存在 JS 对象中,每 30 秒尝试写一次 IndexedDB;失败则记录日志,不中断流程
- 移除复杂索引和多对象库(如 Dexie.js 全量引入),改用原生 IDB API 手动管理单个 objectStore,降低初始化失败概率
离线体验软性降级:不强求“完全离线”,保障核心路径
彻底离线不可达时,聚焦用户最可能需要的“最小可行离线能力”:
- 预缓存仅 3 类资源:HTML 主页、基础 CSS/JS 骨架、
/offline.html页面(由 Service Worker 在 fetch 失败时统一返回) - Ajax 请求失败时,不显示空白或报错弹窗,而是渲染本地 JSON 数据(如
/fallback-data.json)或占位文案(“内容稍后加载”) - 禁用依赖离线存储的功能入口(如“保存到收藏夹”按钮置灰),但保留可见性,附带提示:“此功能需启用网站存储”

















