电商系统用indexeddb管理超大商品缓存,核心是查得快、写得稳、更新准:需拍平字段建索引(如category_name、sale_price)、按查询路径设计复合索引、流式游标分页、增量同步及结构一致性保障。

在电商系统中用 IndexedDB 管理超大容量离线商品缓存,核心不是“存得多”,而是“查得快、写得稳、更新准”。直接把几万条商品 JSON 塞进一个 store,后续搜索、筛选、分页都会卡顿甚至崩溃。必须按电商真实使用场景做结构化设计和性能控制。
拆结构:把商品数据拍平成可索引字段
别把商品对象当黑盒 blob 存。电商常用查询路径是:按类目筛、按价格区间查、按关键词搜、按上架时间排序。对应字段要提前提取并校验:
- 主键用 sku(字符串)或 id(数字),避免 autoIncrement;SKU 更业务友好且唯一
- 把
category.name→ 拍平为 category_name,price.sale→ sale_price,specs.color→ color - 非高频查询字段(如完整描述、富文本详情)压缩进 metadata 字段,仍为 JSON 字符串但不建索引
- 所有索引字段值必须为字符串/数字/日期——null、undefined、NaN 会导致索引失效或报错
建索引:匹配真实查询逻辑,不堆数量
索引不是越多越好,而是要覆盖高频组合查询。比如用户常做“手机类目下价格低于 3000 的新品”,就建复合索引:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
["category_name", "sale_price"]:支持
category_name === "手机" && sale_price - ["category_name", "updated_at"]:支持按类目+时间倒序取最新 20 条
-
["name"] 单字段索引:用于关键词前缀搜索(配合
IDBKeyRange.bound("苹果", "苹果\uffff")) - 避免只为单个字段建一堆索引——
brand、stock、status单独建索引意义不大,除非有独立筛选入口
分片写入:控制事务大小,防阻塞和中断
10 万条商品一次性写入会触发浏览器内存限制或主线程冻结。正确做法是分批 + 批量 + 事务闭环:
- 每批控制在 200–500 条,用
store.put()或store.add()批量提交,不要逐条调用 - 每个批次在一个
readwrite事务中完成,事务结束立即释放资源 - 用递归或 async/await 控制节奏,写完一批再启下一批,中间加
await new Promise(r => setTimeout(r, 0))让出主线程 - 监听
transaction.oncomplete和request.onerror,失败时记录错误 SKU 并跳过,不中断整体流程
流式读取与增量同步
用户滚动浏览商品列表或切换筛选条件时,不能全量加载再 JS 过滤:
- 用
index.openCursor(range)配合IDBKeyRange.bound()查指定范围,边游标遍历边渲染,内存占用恒定 - 分页加载用
cursor.advance(offset)跳过前 N 条,比 offset + limit 更高效 - 后台同步走增量协议:服务端返回
{ added: [...], updated: [...], removed: ["sku123"] },前端分别调用addAll()、put()、delete(),避免全量刷新 - 旧版本商品数据可归档到
products_archive_2026_q2这类只读 store,主 store 保持轻量
不复杂但容易忽略:每次打开数据库后,先检查索引是否存在(store.indexNames.contains("xxx")),再执行查询;写入前确保 keyPath 字段存在且类型正确;缓存失效时优先清空再重建,而不是 patch 更新——结构一致性比节省几毫秒更重要。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










