IndexedDB 是前端结构化数据持久化的核心增强底盘,非缓存替代品;需分层设计、时效管理、索引优化与 Service Worker 协同实现离线优先体验。

前端缓存配合 IndexedDB 存储大量结构化数据,核心在于分层设计 + 异步协作:用 IndexedDB 做底层持久化存储,再通过合理策略(如时效判断、读写调度、索引优化)让它真正“好用”而不是“能用”。
明确缓存角色与 IndexedDB 定位
IndexedDB 不是缓存的替代品,而是缓存的“增强底盘”。它比 localStorage 更适合承担以下任务:
- 存复杂结构:比如带嵌套字段的用户配置、含 timestamp/category/status 的日志列表、带 blob 图片的富文本草稿
- 支持条件查询:靠 createIndex 快速按 category、status、updated_at 等字段筛选,不用全量遍历
- 处理批量操作:一次事务写入上千条记录,避免频繁开闭事务导致卡顿
- 离线优先场景:网络断开时仍可读写,恢复后由业务逻辑决定是否同步到服务端
设计缓存生命周期管理
单纯存进去不够,得管好什么时候用、什么时候更新、什么时候清理:
- 读取时加时效判断:缓存项里必须存 timestamp 字段,读取前对比 Date.now() 和 maxAge(例如 5 分钟),过期则跳过缓存直接请求网络
-
写入时做合并或覆盖:相同 key(如 url 或 id)的新数据直接 put 覆盖旧值;若需保留历史版本,可改用复合 key(如
"user_123_v2")或增加 version 字段 - 定期清理非活跃缓存:比如每月清一次 30 天未访问的页面 HTML 缓存,或按 usageCount 降序删掉最不常用的前 10% 记录
-
主动失效机制:当服务端通知某类数据已变更(如 WebSocket 收到
{"type":"invalidate","key":"dashboard_data"}),就调用 delete 清掉对应 store 中的记录
提升读写性能的关键实操点
大量数据下,慢的不是 API,而是没用对模式:
立即学习“Java免费学习笔记(深入)”;
- 批量写入别单条循环:把 500 条数据塞进一个 add 或 put 请求,而不是 for 循环里每次开新 transaction
-
读取尽量走索引:比如查 “所有 status 为 draft 的表单”,别用 cursor 遍历全表,而要
index.get(IDBKeyRange.only('draft')) - 大对象拆分存储:一张含 10MB 图片的记录,建议把图片存为 Blob 单独放一个 objectStore,主记录只存 url 和 metadata,避免拖慢其他字段读取
-
避免阻塞主线程:大数据量导入时用
setTimeout或requestIdleCallback分片处理,每批 ≤ 100 条,留出渲染时间
搭配 Service Worker 实现真正离线体验
IndexedDB 单独用是“本地数据库”,配上 Service Worker 才变成“离线缓存系统”:
- 拦截 fetch 请求:SW 拦截 GET /api/posts,先查 IndexedDB 是否有对应缓存,有则直接返回,无则转发请求并存入 DB
- 预加载关键资源:APP 初始化时,SW 可主动 openDB 并 fetch 首页所需数据集,提前灌入 IndexedDB,下次打开秒出内容
-
同步失败队列:用户离线提交的表单,存进名为
pendingSync的 objectStore;联网后 SW 启动 background sync,逐条发往服务端并删除本地记录


















