1. 为什么前端需要IndexedDB当我们需要在浏览器中存储超过5MB的数据时传统的localStorage就显得力不从心了。IndexedDB作为浏览器内置的NoSQL数据库可以轻松存储数百MB甚至GB级别的结构化数据。我在开发一个数据可视化仪表盘时就深有体会——当需要缓存数万条历史数据时只有IndexedDB能完美胜任。IndexedDB采用键值对存储方式支持索引查询和事务操作。与WebSQL不同它遵循W3C标准且持续维护更新。最新统计显示全球98%的浏览器都已支持IndexedDB 2.0版本包括移动端的WebView环境。2. 核心概念快速掌握2.1 数据库与对象仓库每个IndexedDB实例包含多个对象仓库(ObjectStore)相当于传统数据库中的表。创建时需要指定主键和索引const request indexedDB.open(myDB, 1); request.onupgradeneeded (event) { const db event.target.result; const store db.createObjectStore(products, { keyPath: id, // 主键 autoIncrement: true }); store.createIndex(category, category, { unique: false }); };注意onupgradeneeded是唯一能修改数据库结构的地方版本号变更时会自动触发2.2 事务的四种模式模式描述适用场景readonly只读访问数据查询readwrite读写权限数据变更versionchange结构变更数据库升级cleanup特殊维护异常恢复实际开发中最常用的是readwrite事务const tx db.transaction(products, readwrite); const store tx.objectStore(products); store.add({name: Phone, price: 599});3. 实战CRUD操作3.1 批量写入优化直接循环add()会导致性能问题正确做法是复用事务function batchAdd(store, items) { return new Promise((resolve, reject) { const tx store.transaction; let completed 0; items.forEach(item { const req store.add(item); req.onsuccess () { if (completed items.length) { resolve(); } }; req.onerror reject; }); }); }3.2 高级查询技巧组合使用索引和游标可以实现复杂查询function queryByPriceRange(store, min, max) { const range IDBKeyRange.bound(min, max); const index store.index(price); const request index.openCursor(range); const results []; return new Promise(resolve { request.onsuccess (e) { const cursor e.target.result; if (cursor) { results.push(cursor.value); cursor.continue(); } else { resolve(results); } }; }); }4. 性能调优实战4.1 索引设计原则对高频查询字段建立索引组合索引字段顺序很重要避免对频繁更新的字段建索引唯一索引能加速精确查找4.2 事务隔离技巧// 错误示范嵌套事务 db.transaction(store1, () { db.transaction(store2, () { /*...*/ }); }); // 正确做法单事务多store db.transaction([store1, store2], () { /*...*/ });5. 常见问题排查5.1 版本冲突处理const openRequest indexedDB.open(db, 2); openRequest.onblocked () { console.warn(请关闭其他页面的数据库连接); }; openRequest.onupgradeneeded (e) { if (e.oldVersion 1) { // 初始版本升级逻辑 } if (e.oldVersion 2) { // v1-v2迁移逻辑 } };5.2 存储空间监控navigator.storage.estimate().then(({usage, quota}) { console.log(已用: ${usage} bytes); console.log(限额: ${quota} bytes); });6. 现代框架集成6.1 与Vue/React配合推荐使用Dexie.js这类封装库const db new Dexie(ShopDB); db.version(1).stores({ products: id,name,price, orders: id,date,customer }); // 响应式查询 const products Vue.ref([]); db.products.where(price).above(100).toArray() .then(items products.value items);6.2 Service Worker缓存IndexedDB是PWA应用的核心存储方案self.addEventListener(fetch, (e) { if (e.request.url.includes(/api/data)) { e.respondWith( caches.match(e.request) .then(cached cached || fetchAndCache(e.request)) ); } }); async function fetchAndCache(request) { const res await fetch(request); const clone res.clone(); const db await openDB(apiCache); db.put(responses, await res.json()); return clone; }7. 实战建议对于简单状态管理优先考虑localStorage超过10MB数据量时推荐使用IndexedDB敏感数据记得加密存储定期清理过期数据使用Promise封装所有异步操作我在电商后台项目中将商品SKU数据(约15MB)存入IndexedDB后页面加载速度提升了300%。关键是要合理设计索引避免全表扫描。