IndexedDB批量写入应复用同一readwrite事务,避免循环中重复开启;单事务控制在100–500条(依数据大小调整),分块+Promise链处理大数据;只读操作用readonly,写完监听oncomplete清理,同时捕获onabort。

IndexedDB 批量写入的核心不是“多调用几次 add”,而是把数据塞进同一个 readwrite 事务里一次性提交。跨事务的“批量”只是假象,既不省时间,也不保原子性。
复用事务,别在循环里反复开
每次调用 db.transaction() 都有开销,频繁开启还会触发浏览器内部资源调度,拖慢整体速度。正确做法是:先开一个事务,再把所有数据交给它处理。
- 打开事务后,立刻获取 objectStore,不要等每条数据都去重取
- 用
forEach或for循环调用store.add(item)或store.put(item),全部挂载到同一事务上 - 事务自动在所有请求发出后提交,无需手动
commit
控制单次事务的数据量
一次塞太多(比如上万条)容易导致内存飙升、事务超时或被浏览器强制中止。1000 条是个经验上限,实际要按单条数据大小动态调整。
- 若单条记录平均 2KB,建议每事务 200–500 条
- 若含 Blob 或大文本字段,降到 50–100 条更稳妥
- 大数据导入时,主动分块:把原始数组切片,每块走一个独立事务
用 Promise 封装,避免回调地狱和竞态
原生 IndexedDB 是事件驱动,容易嵌套混乱。现代写法应统一转为 Promise 链,确保顺序执行、错误可捕获。
- 每个操作(open、add、get)都封装成返回 Promise 的函数,失败时
reject带结构化错误信息 - 需要“先查再写”的逻辑,直接
await get(...)后接await put(...),不用监听onsuccess - 非关键操作(如日志落库)可用
queueMicrotask推迟到当前任务之后,防阻塞渲染
只读用 readonly,写完立刻释放
事务生命周期越短越好,但不能“过早释放”。关键点在于语义匹配和时机把握。
- 纯查询一律用
'readonly',哪怕后面还要写——复用 readwrite 事务反而增加锁竞争 - 写操作完成后,靠监听
transaction.oncomplete做清理(如更新 UI 状态、释放临时引用) - 务必监听
onabort而不只是onerror,因为同库其他操作可能强行终止当前事务



















