IndexedDB 适合存储结构复杂、体积较大、需离线可用的前端状态树快照,关键在于可靠设计:按语义拆分 object store、预处理序列化、事务控制与错误降级、快照清理、结构校验与版本迁移。

IndexedDB 是浏览器内置的持久化键值存储,适合缓存结构复杂、体积较大、需离线可用的前端状态树快照。关键不在于“能不能存”,而在于“怎么设计才可靠、可恢复、易维护”。
用对象存储(Object Store)建模状态树
状态树通常为嵌套对象或数组(如 Redux store 或 Zustand 的 snapshot),不能直接存为字符串——要保留结构可查询性与增量更新能力。建议按语义拆分为多个 object store:
- 主状态快照存入 state_snapshots store,主键用时间戳 + 唯一标识(如
"20240520-142305-v1"),值为完整状态对象 - 高频变更子树(如表单草稿、临时筛选条件)单独存入 drafts 或 ui_state store,主键用模块路径(如
"user/profile/form") - 为支持按时间回溯,可在 store 中添加
createdAt和version字段,并建立索引:store.createIndex('byTime', 'createdAt', { descending: true })
序列化前做轻量预处理
直接 JSON.stringify() 可能失败(含函数、循环引用、Date/RegExp/Map/Set 等)。推荐两步处理:
- 用 structuredClone()(现代浏览器支持)深拷贝原始状态,安全剔除不可序列化字段
- 对剩余数据做标准化:将
Date转为 ISO 字符串,Map/Set转为数组,移除undefined和 symbol 键;也可用 structuredClone 兼容方案(如flatted库)
事务控制 + 错误降级策略
写入状态快照应包裹在 readwrite 事务中,避免并发冲突:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 失败时不要静默丢弃:捕获
transaction.onabort和request.onerror,记录错误并 fallback 到内存缓存(如sessionStorage) - 读取时优先尝试最新快照,若失败(DB 被删、版本升级),自动降级到上一个有效快照或初始默认状态
- 限制快照数量(如只保留最近 5 个),用游标遍历 +
delete()清理旧项,避免 DB 膨胀
恢复时做结构校验与兼容映射
从 IndexedDB 读出快照后,不能直接赋值给应用状态——需验证完整性并适配版本差异:
- 检查关键字段是否存在(如
user.id、router.path),缺失则视为损坏快照,跳过加载 - 若状态结构随版本迭代变化(如 v2 删除了
theme.mode字段),用迁移函数做字段映射:if (snapshot.version === 1) { snapshot.theme = { mode: snapshot.darkMode ? 'dark' : 'light' }; } - 恢复完成后再触发 UI 渲染,避免中间态闪烁;可用 Promise 包装整个恢复流程,配合 loading 状态控制
不复杂但容易忽略:IndexedDB 的异步本质要求状态恢复必须是显式、可中断、可重试的流程。把快照当“快照”用,而不是当“实时同步通道”依赖。

















