pwa 全离线运行需 service worker 与 indexeddb 协作:前者用 cache api 缓存 html/css/js 等静态资源,后者存储带 syncstatus 和 op 字段的业务数据,并通过时间戳索引实现联网后自动同步。

要让 PWA 真正做到全离线运行,光靠缓存 HTML/CSS/JS 不够——用户还得能读文章、查记录、填表单、甚至修改再保存。这需要 IndexedDB 和 Service Worker 各司其职、紧密配合:前者管“数据怎么存、怎么查”,后者管“请求怎么拦、资源怎么给”。两者不混用、不替代,而是分工协作。
静态资源交给 Cache API,别塞进 IndexedDB
Service Worker 的 install 阶段用 caches.open('static-v1') 预缓存关键路径,比如 ['/', '/index.html', '/assets/app.js']。这些是 UI 骨架,必须秒开。IndexedDB 不适合存这类二进制或文本资源——它没 HTTP 缓存语义,也不支持直接响应 fetch 请求。硬往里塞图片或 HTML 字符串,会拖慢打开速度,还容易触发 GC 压力或类型错误(比如 TypeError: Request destination is not 'document')。
业务数据用 IndexedDB 存,带同步状态字段
在页面 JS 中初始化数据库(别在 SW 里 open,避免阻塞),建 objectStore 存笔记、文章、草稿等。关键设计点:
- 主键设为
id,确保唯一性 - 加索引字段如
updatedAt(时间戳)和syncStatus(值为'pending'/'synced'/'failed') - 每条记录附带操作类型
op: 'create' | 'update' | 'delete',方便后续同步时精准执行
离线加载流程:先壳后内容,分层兜底
用户访问 /post/123 时,实际发生的是一个协同链路:
- Service Worker 拦截请求,用
caches.match()返回已缓存的 HTML 模板(App Shell) - 页面加载后,JS 立即调用
indexedDB.open(),从对应 objectStore 读取 id=123 的文章数据 - 若查到,立刻渲染;同时发起网络请求尝试更新本地数据(Stale-While-Revalidate)
- 若没查到,显示“暂无内容”或 fallback 到离线页(如
/offline.html)
联网后自动同步:靠时间戳 + 后台任务
用户编辑并保存后,数据写入 IndexedDB 并标记 syncStatus: 'pending'。网络恢复时:
- 监听
navigator.onLine或使用 Background Sync API 触发同步任务 - 按
updatedAt索引反向遍历待同步记录(IDBKeyRange.lowerBound(lastSyncTime, 'prev')) - 逐条发送到服务端,接口需幂等(建议带
X-Request-ID去重) - 成功则更新本地
syncStatus和serverId;失败则累加errorCount,超 3 次降级为手动同步,并在 UI 提示“有 X 条未同步”
不复杂但容易忽略:SW 更新后,旧缓存和旧 DB 版本得主动清理。新版 SW 安装时,要调用 caches.keys() 删除旧 cache,同时在 onupgradeneeded 中迁移 schema——否则用户永远跑在老逻辑上。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











