瀏覽器原理中階
你知道 localStorage 但你知道 IndexedDB 嗎?
什麼是 IndexedDB?
IndexedDB 是瀏覽器內建的非關聯式(NoSQL)資料庫,讓前端可以在本地端儲存大量結構化資料(物件、Blob、檔案…),支援索引、事務(Transaction)和非同步操作。
localStorage vs IndexedDB
| 特性 | localStorage | IndexedDB |
|---|---|---|
| 儲存類型 | 字串 key-value | 任意 JS 物件(含 Blob、File) |
| 容量 | ~5–10 MB | 通常 ≥ 250 MB(依裝置) |
| 存取方式 | 同步 | 非同步(事件 / Promise) |
| 索引 / 查詢 | 無 | 有(可建立 index) |
| 事務(Transaction) | 無 | 有(ACID) |
| 適合場景 | 小型設定值 | 大量資料、離線應用(PWA) |
核心概念
- Database:最高層級容器,有版本號(version)
- Object Store:類似 SQL 的資料表,儲存物件
- Index:建立在物件屬性上的索引,加速查詢
- Transaction:讀寫操作必須在事務中執行,保證資料一致性
- Cursor:用於遍歷大量資料
基本使用範例(原生 API)
// 開啟資料庫
const request = indexedDB.open('myDB', 1);
request.onupgradeneeded = (e) => {
const db = e.target.result;
// 建立 object store
const store = db.createObjectStore('users', { keyPath: 'id' });
store.createIndex('name', 'name', { unique: false });
};
request.onsuccess = (e) => {
const db = e.target.result;
// 寫入資料(readwrite 事務)
const tx = db.transaction('users', 'readwrite');
tx.objectStore('users').add({ id: 1, name: 'Alice', age: 30 });
// 讀取資料(readonly 事務)
const tx2 = db.transaction('users', 'readonly');
const getReq = tx2.objectStore('users').get(1);
getReq.onsuccess = () => console.log(getReq.result); // { id: 1, name: 'Alice', age: 30 }
};
用 Promise 封裝(或使用 idb 函式庫)
原生 API 是事件驅動,較繁瑣。推薦使用 idb 函式庫(Google Jake Archibald 開發):
import { openDB } from 'idb';
const db = await openDB('myDB', 1, {
upgrade(db) {
db.createObjectStore('users', { keyPath: 'id' });
},
});
await db.put('users', { id: 1, name: 'Alice', age: 30 });
const user = await db.get('users', 1);
console.log(user); // { id: 1, name: 'Alice', age: 30 }
常見應用場景
- PWA 離線快取:快取 API 回應、大型資產
- Draft 自動儲存:文章草稿、表單填寫進度
- 前端分頁資料:客戶端大量資料排序、篩選
- 離線優先(Offline First)應用
小結
當你需要在瀏覽器端儲存:
- 超過幾 MB 的資料 → IndexedDB
- 複雜結構、需要查詢、索引 → IndexedDB
- 簡單的 key-value 少量設定 → localStorage
✦ AI 模擬面試
輸入你的答案,AI 即時分析精準度與改進空間
登入後即可使用 AI 評分
