indexeddb 必须严格管理版本控制、事务边界和索引设计才能支撑大数据量。需在 onupgradeneeded 中按 oldversion 分段建库建索引;查大量数据须用 cursor + index 分块遍历,禁用 getall();写操作须监听 abort/error 并及时 abort() 避免事务锁。

IndexedDB 不是“能用就行”的存储方案,而是必须明确版本控制、事务边界和索引设计才能撑住大数据量的本地数据库。盲目调用 add() 或 put() 写入万条记录,大概率触发事务自动中止或内存溢出。
数据库打开与版本升级必须分清 oldVersion 和 newVersion
浏览器只在 onupgradeneeded 中允许结构变更,且该事件仅当传入的版本号 > 当前数据库版本时才触发。常见错误是反复用同一版本号打开,导致新 createObjectStore() 被跳过,后续写入直接报 NotFoundError。
-
indexedDB.open('mydb', 2)打开时若当前库版本为 1,则触发onupgradeneeded,event.oldVersion === 1,event.newVersion === 2 - 若当前已是版本 2,再用
indexedDB.open('mydb', 2),则跳过onupgradeneeded,直接走onsuccess - 升级逻辑必须按 oldVersion 分段写:比如
if (oldVersion 、<code>if (oldVersion ,不能只写 <code>if (oldVersion === 1)
写入万级数据必须拆事务 + 控制游标批量
单个事务内写入超过几千条记录,Chrome 会因内存压力静默失败(不抛错,但 transaction.oncomplete 不触发);Safari 更激进,常在 500 条左右就中断。不能依赖“一次全写”。
- 用
transaction.oncomplete而非request.onsuccess判断整批是否成功 - 每批控制在 100–300 条,用递归或
setTimeout分片提交,避免阻塞事件循环 - 对大数组写入,优先用
objectStore.put(item, key)而非add(),避免主键冲突中断整批
function batchWrite(store, items, offset = 0, batchSize = 200) {
const tx = db.transaction([store.name], 'readwrite');
const os = tx.objectStore(store.name);
const chunk = items.slice(offset, offset + batchSize);
chunk.forEach(item => os.put(item));
tx.oncomplete = () => {
if (offset + batchSize console.error('batch write failed:', e.target.error);
}
查大量数据别用 get() 或 getAll(),改用 cursor + index
getAll() 加载全部记录到内存,10 万条对象轻松吃掉 200MB+ JS 堆内存,页面卡死;get(key) 只适合精确主键查询。真要遍历或条件查,必须靠游标(IDBCursor)配合索引。
- 先确保已建索引:
store.createIndex('status', 'status') - 用
index.openCursor(IDBKeyRange.only('active'))按索引查,而非扫全表 - 游标遍历中用
cursor.continue()分块处理,每次只拿几十条,避免堆爆炸 - 需要总数?别
getAll().length,改用index.count(IDBKeyRange.only('active'))
删除旧数据必须显式 abort() 避免残留事务锁
IndexedDB 的事务不会自动释放,尤其在页面刷新或异常退出时。如果一个写事务没结束就被中断,后续所有对该 objectStore 的操作都会挂起,直到超时(通常 60 秒)后报 TransactionInactiveError。
- 所有写操作必须监听
transaction.onabort和transaction.onerror,并做清理标记 - 批量删除前加判断:
if (transaction.readyState === 'active') { transaction.abort(); } - 长期运行的同步任务(如离线队列上传),建议每次只处理一个事务,完成后立即释放
真正卡住 IndexedDB 的,从来不是容量上限,而是事务生命周期管理失当、索引缺失导致全表扫描、以及把异步 API 当同步用——这些细节在小数据量时完全不暴露,一到真实场景就崩得毫无征兆。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











