IndexedDB缓存API响应需精细控制读写时机:按业务敏感度分级设TTL或跳过缓存,用URL+参数生成唯一cacheKey,失败自动降级,定期清理过期数据。

直接用 IndexedDB 缓存 API 响应,能明显加快二次加载——但关键不在“存”,而在“什么时候读缓存、什么时候发请求”。策略没设好,反而容易展示过期数据。
明确缓存新鲜度,避免数据滞后
不能一有缓存就返回。建议按业务敏感度分级处理:
- 对变动不频繁的数据(如用户资料、配置项、静态列表),设 TTL(例如 5 分钟):写入时记下 lastUpdated: Date.now(),读取前判断 当前时间 - lastUpdated < 300000,满足才用缓存
- 对强一致性要求高的接口(如余额、订单状态),默认跳过缓存;或加强制刷新参数(如 ?_t=123456789)绕过缓存逻辑
- 支持 stale-while-revalidate:缓存超时后仍先返回旧数据,同时后台静默拉新,兼顾体验与准确
用 URL + 参数生成唯一 cacheKey
同一个接口带不同 query 或 body,必须视为不同条目。否则会错乱覆盖。
- 推荐 key 格式:`${url}|${JSON.stringify(params)}`(注意提前过滤 token、auth 等敏感字段)
- 创建 objectStore 时设 keyPath: 'cacheKey',查询时直接 store.get(cacheKey),比遍历快得多
- 避免把整个响应体当 key,既低效又易冲突
失败时自动降级,不卡主流程
IndexedDB 可能被禁用、配额满、事务失败——这些都不能影响正常请求。
- 打开数据库失败 → 直接走 fetch,不报错、不阻塞
- 读缓存出错(如数据损坏)→ 捕获异常,继续发网络请求,并顺手 delete(cacheKey) 清理脏数据
- 写缓存失败(如超出 quota)→ 记 warning 日志,但不影响响应主体返回
定期清理,防止无限膨胀
长期运行的单页应用,缓存不清理会越积越多,还可能堆积过期/无效数据。
- 每条记录写入时加 expiresAt: Date.now() + 24 * 60 * 60 * 1000(比如 1 天)
- 读取前先校验 expiresAt > Date.now(),过期则跳过并触发后台更新
- 利用页面隐藏(visibilitychange)或定时器,在空闲时批量清理:删除 lastUpdated 超过 7 天 的记录
- 用户登出、切换账号等操作后,清空全部相关缓存
不复杂但容易忽略。核心是把缓存当成“有生命周期的副产物”,而不是“万能加速开关”。

















