浏览器缓存之【结构化数据库与缓存】: IndexedDB、Cache storage 和 Storage buckets

浏览器缓存之【结构化数据库与缓存】:IndexedDB、Cache storage 和 Storage buckets

在现代 Web 开发中,前端缓存已不再局限于简单的 Cookie 和 LocalStorage。随着 PWA(渐进式 Web 应用)和离线优先架构的普及,浏览器提供了更强大的结构化存储方案。本文将深入探讨 IndexedDB、Cache Storage 和 Storage buckets 这三大核心缓存技术,并通过实战代码演示其应用。## IndexedDB:客户端 NoSQL 数据库IndexedDB 是一个基于事务的、键值对存储的 NoSQL 数据库,支持复杂的数据结构(如对象、数组和 Blob)。它非常适合存储大量结构化数据,例如用户配置、离线表单数据或游戏进度。### 核心特性- 异步 API :所有操作都是异步的,不会阻塞 UI 线程。- 事务支持 :保证数据一致性。- 索引能力 :可以按非主键字段进行高效查询。- 大容量存储 :远超 LocalStorage(通常 5MB 限制)的限制。### 实战代码:实现待办事项管理器javascript// 打开/创建 IndexedDB 数据库const DB_NAME = 'TodoDB';const DB_VERSION = 1;const STORE_NAME = 'todos';function openDB() { return new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); request.onupgradeneeded = (event) => { const db = event.target.result; // 创建对象仓库(相当于表),使用 autoIncrement 主键 if (!db.objectStoreNames.contains(STORE_NAME)) { const store = db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true }); // 创建索引:按完成状态查询 store.createIndex('completed', 'completed', { unique: false }); // 创建索引:按创建时间排序 store.createIndex('createdAt', 'createdAt', { unique: false }); } }; request.onsuccess = (event) => resolve(event.target.result); request.onerror = (event) => reject(event.target.error); });}// 添加待办事项async function addTodo(text) { const db = await openDB(); const transaction = db.transaction(STORE_NAME, 'readwrite'); const store = transaction.objectStore(STORE_NAME); const todo = { text: text, completed: false, createdAt: new Date().toISOString() }; const request = store.add(todo); return new Promise((resolve, reject) => { request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); transaction.oncomplete = () => db.close(); // 关闭数据库连接 });}// 查询所有未完成的待办事项(使用索引)async function getUncompletedTodos() { const db = await openDB(); const transaction = db.transaction(STORE_NAME, 'readonly'); const store = transaction.objectStore(STORE_NAME); const index = store.index('completed'); // 使用 IDBKeyRange 筛选 completed = false 的记录 const range = IDBKeyRange.only(false); const request = index.openCursor(range); const todos = []; return new Promise((resolve, reject) => { request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { todos.push(cursor.value); cursor.continue(); } else { resolve(todos); } }; request.onerror = () => reject(request.error); transaction.oncomplete = () => db.close(); });}// 使用示例(async () => { await addTodo('学习 IndexedDB'); await addTodo('编写技术文章'); const todos = await getUncompletedTodos(); console.log('未完成的待办事项:', todos);})();## Cache Storage:离线资源缓存利器Cache Storage 是 Service Worker 的核心伴侣,专门用于缓存 HTTP 请求和响应。它支持精细的缓存策略控制,是构建离线应用的关键技术。### 核心特性- 基于请求-响应 :缓存网络请求的完整响应。- 版本化缓存 :可以创建多个命名缓存实例。- 与 Service Worker 深度集成 :拦截网络请求并提供离线支持。- 自动过期管理 :虽然不自动过期,但可以手动清理。### 实战代码:Service Worker 中的缓存策略javascript// service-worker.jsconst CACHE_NAME = 'app-v3';const STATIC_ASSETS = [ '/', '/index.html', '/styles/main.css', '/scripts/app.js', '/images/logo.png'];// 安装阶段:预缓存静态资源self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { console.log('预缓存静态资源...'); return cache.addAll(STATIC_ASSETS); }) );});// 激活阶段:清理旧缓存self.addEventListener('activate', (event) => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames.map((cacheName) => { if (cacheWhitelist.indexOf(cacheName) === -1) { console.log('删除旧缓存:', cacheName); return caches.delete(cacheName); } }) ); }) );});// 拦截网络请求:实现 Stale-While-Revalidate 策略self.addEventListener('fetch', (event) => { // 只处理 GET 请求 if (event.request.method !== 'GET') return; event.respondWith( caches.match(event.request).then((cachedResponse) => { // 先返回缓存内容(如果有) const fetchPromise = fetch(event.request).then((networkResponse) => { // 更新缓存(如果请求成功) if (networkResponse && networkResponse.status === 200) { const responseClone = networkResponse.clone(); caches.open(CACHE_NAME).then((cache) => { cache.put(event.request, responseClone); }); } return networkResponse; }).catch((error) => { console.error('网络请求失败:', error); return cachedResponse; // 降级到缓存 }); return cachedResponse || fetchPromise; }) );});// 主线程注册 Service Worker// navigator.serviceWorker.register('/service-worker.js')// .then(registration => console.log('SW 注册成功'))// .catch(error => console.error('SW 注册失败:', error));## Storage buckets:统一存储管理新标准Storage buckets 是较新的 Web 标准(Chrome 104+ 支持),旨在为不同来源的存储提供统一的配额管理和优先级控制。它解决了 IndexedDB 和 Cache Storage 存储空间不可控的问题。### 核心特性- 存储桶隔离 :每个来源可以有多个存储桶,彼此隔离。- 配额管理 :可以设置持久化或临时存储桶。- 优先级控制 :低优先级存储桶在空间不足时优先被清除。- 统一 API :兼容 IndexedDB、Cache Storage 和 Origin Private File System。### 实战代码:使用 Storage buckets 管理存储空间javascript// 检查浏览器是否支持 Storage bucketsif ('storageBuckets' in navigator) { console.log('Storage buckets 可用'); // 创建持久化存储桶 const bucketConfig = { name: 'user-data', durability: 'strict', // 'strict' | 'relaxed' 控制写入持久性 estimatedSize: 1024 * 1024 * 50 // 预估大小 50MB }; navigator.storageBuckets.open(bucketConfig) .then(bucket => { // 在存储桶中打开 IndexedDB const dbRequest = bucket.indexedDB.open('MyAppDB', 1); dbRequest.onupgradeneeded = (event) => { const db = event.target.result; if (!db.objectStoreNames.contains('items')) { db.createObjectStore('items', { keyPath: 'id' }); } }; // 在存储桶中打开 Cache bucket.caches.open('api-cache').then(cache => { cache.add('/api/data.json'); }); // 获取存储桶的配额信息 return bucket.estimate(); }) .then(estimate => { console.log('存储桶使用情况:', { usage: estimate.usage, quota: estimate.quota, usagePercent: (estimate.usage / estimate.quota * 100).toFixed(2) + '%' }); }); // 监听存储桶空间不足事件 navigator.storage.addEventListener('quotachange', (event) => { console.log('存储配额发生变化:', event); // 可以在此触发清理低优先级缓存 }); // 列出所有存储桶 navigator.storageBuckets.keys().then(bucketNames => { console.log('当前存储桶:', bucketNames); });} else { console.log('浏览器不支持 Storage buckets,使用传统存储方式');}## 三种技术的对比与选择| 特性 | IndexedDB | Cache Storage | Storage buckets ||------|-----------|---------------|-----------------|| 数据模型 | 键值对 + 索引 | 请求-响应 | 存储桶容器 || 适用场景 | 结构化数据存储 | HTTP 资源缓存 | 存储空间管理 || 容量 | 大(通常是磁盘剩余空间) | 大 | 可配置 || 持久性 | 默认非持久 | 默认非持久 | 可指定持久 || 浏览器支持 | 广泛 | 广泛 | 较新(Chrome 104+)|| 清除策略 | 无自动清除 | 可手动清除 | 支持优先级清除 |## 总结IndexedDB 适合存储复杂的结构化数据,如用户生成的内容或离线表单;Cache Storage 是为 Service Worker 量身定制的 HTTP 缓存解决方案,适合离线资源管理;Storage buckets 则提供了更高级的存储管理能力,特别适合需要精细控制存储空间的 PWA 应用。在实际开发中,建议组合使用这三种技术:用 Cache Storage 缓存静态资源和 API 响应,用 IndexedDB 存储用户数据,用 Storage buckets 统一管理存储配额。这样的架构既能保证离线可用性,又能高效管理存储空间。随着 Web 平台的发展,这些 API 将持续演进,为开发者提供更强大的离线能力。

相关推荐
SelectDB1 小时前
SelectDB search():AI 日志搜索与分析场景的技术能力与实践
数据库
SelectDB1 小时前
Apache Doris 事务保障:技术能力、选型对比与企业实践
数据库
SelectDB1 小时前
AI Observe Stack(基于 Apache Doris):AI Agent 可观测性技术能力、选型对比与实践
数据库
SelectDB1 小时前
PostgreSQL + Apache Doris HTAP 架构:技术能力、选型对比与企业实践
数据库
SelectDB1 小时前
SelectDB(飞轮科技)技术研发型企业认证:Apache Doris 核心能力、选型对比与实践
数据库
古月方枘Fry1 小时前
基于大模型+MySQL的innoai助手(可适配多数环境)
网络·数据库·mysql·aigc
Databend2 小时前
从全表排序到概率统计:Databend 如何用 KLL、Top-N 与 CMS 改进基数估计
大数据·数据库·算法
bonechips2 小时前
RAG实战(一):EPUB 加载、文本切割与向量入库
前端·数据库