用IndexedDB彻底接管PWA缓存

产品狗小林 初级 6小时前 更新于 2026年7月27日 392 浏览 15 点赞 约 1 分钟

把Service Worker(SW)当成代理层拦截请求是常规操作,但Spirit这套方案最激进的地方在于它把 spirit-sw.js 定义成了“固件”而不是中间件。说白了,它根本不让浏览器去管缓存,而是让应用自己掌控生死。

传统的PWA安装和更新逻辑全在浏览器手里,经常会出现SW更新了但没激活,或者缓存版本冲突这种恶心事。Spirit的逻辑是:SW只负责启动,剩下的全部塞进IndexedDB。

这套架构由四个部分组成:

  • spirit-grave.js:纯粹的存储层,把文件当成Blob塞进IndexedDB,只管埋进去和挖出来。
  • spirit-reg.js:安装程序,首次访问时读取 spirit-manifest.json,把所有资源同步到IDB。
  • spirit-sw.js:这就是那个“引导加载程序”。它不处理缓存,而是直接返回一段硬编码的HTML字符串,这段代码会从IDB里把CSS、JS和图片全部还原出来。启动时零网络请求。
  • spirit-revive.js:更新机制。只有调用 Spirit.reviveFromNetwork() 才会去检查更新,完全由应用决定什么时候更新,而不是被浏览器在后台偷偷搞。
用IndexedDB彻底接管PWA缓存

对比一下启动流程,差别挺大:

常规PWA:
请求URL → SW拦截 → 检查Cache → 返回缓存或请求网络 → 异步检查SW更新 → 等待标签页关闭 → 激活新版本。

Spirit模式:
请求URL → SW直接甩出一个硬编码的引导字符串 → 引导程序从IDB重建应用 → 运行。

这种实操方案最大的好处是确定性。不管是离线还是在线,启动路径完全一样,不存在所谓的“缓存失效”或“版本漂移”。

如果你在做那种对版本控制要求极高、且不能容忍浏览器随机更新导致页面崩溃的Web App,这种把资源“埋”在IDB里的做法非常值得参考。

配置逻辑大概是这样的:

// spirit-manifest.json 示例
{
  "files": [
    { "path": "/index.html", "hash": "a1b2c3d4" },
    { "path": "/css/main.css", "hash": "e5f6g7h8" },
    { "path": "/js/app.js", "hash": "i9j0k1l2" }
  ]
}

然后通过 JS 调用更新:

// 只有在需要更新时才手动触发
Spirit.reviveFromNetwork().then(() => {
  console.log('资源已更新,准备刷新页面');
  window.location.reload();
});
AI编程AI编程实战architecturejavascriptsoftwaredevelopment

全部回复 (4)

小李爱学习 初级 13小时前
确实,我之前做离线地图就这么搞,比Cache API好控多了。
0 回复
创业者阿杰 中级 13小时前
得注意下存储配额,某些浏览器清理空间时会把IDB给删了。
0 回复
老大鹏 专家 13小时前
之前试过,记得给IDB加个版本管理,不然升级时容易卡死。
0 回复
自由职业运营喵 高级 13小时前
@老大鹏 这就对了,之前我就被版本号坑过,现在你是怎么处理迁移逻辑的?
0 回复

发表回复

支持 Markdown 格式