尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

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

浏览器缓存之【结构化数据库与缓存】: IndexedDB、Cache storage 和 Storage buckets
📅 发布时间:2026/6/29 19:11:04

前文已经介绍了,基础键值存储 Local storage 和 Session storage,那么本文再介绍另一新的类别:结构化数据库与缓存。

结构化数据库与缓存,涵盖 IndexedDB、Cache storage 和 Storage buckets。

  • IndexedDB 是一个事务型数据库,支持存储大量结构化数据,适合复杂应用如离线文档编辑器或媒体播放器,属于应用数据存储;
  • Cache storage 主要用于 Service Worker缓存网络资源,实现离线访问和快速加载,属于资源性能存储;
  • Storage buckets 则是更底层的存储分区机制,允许开发者按策略管理存储空间,常用于大型应用的资源隔离与配额控制,属于资源性能存储。

下面来详细介绍下。

回到顶部

一、什么是 IndexedDB?

1.1 简介

IndexedDB 是浏览器提供的客户端事务型 NoSQL 数据库,专为存储大量结构化数据而设计,支持异步操作、事务机制和索引查询,适用于构建离线优先的 Web 应用(如:PWA-Progressive Web App,渐进式 Web 应用)。

其核心价值在于突破 localStorage 的容量与性能限制,允许直接存储复杂对象、二进制数据(Blob),并通过索引实现高效查询,同时避免阻塞主线程。

IndexedDB 是 W3C 推荐的浏览器原生客户端数据库标准,作为 WebSQL 被弃用后的主流替代方案。它属于 NoSQL 类型数据库,以对象仓库(Object Store)而非表格形式组织数据,数据以键值对形式存储,支持 JavaScript 对象、数组、Blob 等复杂类型,无需序列化。

若需简化开发,可使用封装库(如:Dexie.js、localForage),它们提供 Promise API 和自动降级支持,大幅降低原生 IndexedDB 的复杂度。实际项目中,应优先评估数据规模与查询需求——当数据量 >100KB 或需复杂查询时,IndexedDB 是比 localStorage 更可靠的选择。

与 localStorage/WebSQL 的关键区别:

对比维度localStorage / WebSQLIndexedDB
容量上限通常限制为 5MB,且同步操作易阻塞 UI无固定上限(一般 ≥250MB,可达设备空闲磁盘的 50%~60%)
数据操作方式仅支持字符串键值对,无索引和事务支持通过事务机制保证数据一致性,并支持多字段索引加速查询
同步性操作是同步的,大数据量时会导致界面卡顿完全异步,通过事件或 Promise 执行,不阻塞主线程

1.2 关键特性

1)核心能力

事务支持:操作必须在事务中执行,支持 readonly 和 readwrite 模式。事务具备原子性——任一操作失败则整个事务回滚,确保数据一致性。
索引优化查询:可为对象仓库的任意字段创建索引(如:name、updated_at),避免全表扫描。时间范围查询需配合 IDBKeyRange.bound() 使用。
二进制数据存储:直接存储 Blob/File 对象(如:图片、视频),无需转换为 Base64 字符串,适用于离线资源缓存。

2)限制与约束

同源策略:数据库仅限创建它的同源页面访问,无法跨域读写。
版本控制机制:数据库通过整数版本号管理结构变更。版本号必须为整数(如:2.1 会被取整为 2),升级时需触发 onupgradeneeded 事件迁移数据。
隐身模式行为:数据仅驻留在内存中,关闭窗口后自动清除,且配额通常 ≤120MB(常规模式可达数 GB)。

1.3 核心概念架构

1)核心组件

组件说明
数据库顶层容器,每个数据库有唯一名称和整数版本号。
对象仓库类似 NoSQL 的“集合”,存储键值对数据。必须指定主键路径(keyPath)。
索引基于字段的快速查询通道,可设为唯一(unique: true)或非唯一。
事务操作的原子单元,限定作用域(如:db.transaction(['users'], 'readwrite'))。

2)数据组织逻辑

主键设计:优先使用业务主键(如:user_id、message_id)作为 keyPath,避免依赖自增 ID(autoIncrement)导致多端同步冲突。
分域存储:按业务拆分对象仓库(如:user_settings、chat_messages),避免单表膨胀导致锁竞争。

1.4 基本操作:初始化、增、删、改、查、索引查询

// 【初始化】
const request = indexedDB.open("MyDB", 1); // 名称+版本号
// 首次创建或升级版本时触发
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 创建对象仓库(主键为 id)
const store = db.createObjectStore("users", { keyPath: "id" });
// 为name字段添加索引
store.createIndex("name", "name", { unique: false });
};
request.onsuccess = (event) => {
const db = event.target.result; // 获取数据库实例
};
// 关键点:版本升级逻辑必须在 onupgradeneeded 中完成,否则无法修改结构
const tx = db.transaction("users", "readwrite");
const store = tx.objectStore("users");
// 【添加数据 add】
const request = store.add({ id: 1, name: "Alice", age: 25 }); // 主键需唯一
request.onsuccess = () => console.log('数据添加成功');
request.onerror = (event) => console.error('数据添加失败:', event.target.errorCode);
// 【删除数据 delete】
const request = store.delete(id);
request.onsuccess = () => console.log('数据删除成功');
request.onerror = (event) => console.error('数据删除失败:', event.target.errorCode);
// 【修改】
const request = store.put({ id: 1, name: "Alice", age: 26 });
request.onsuccess = () => console.log('数据更新成功');
request.onerror = (event) => console.error('数据更新失败:', event.target.errorCode);
// 【简单查询 get】
const request = store.get(id);
request.onsuccess = (event) => {
if (event.target.result) {
console.log('查询结果:', event.target.result);
} else {
console.log('未找到 ID 为', id, '的数据');
}
};
request.onerror = (event) => console.error('数据查询失败:', event.target.errorCode);
// 【索引查询】
const index = store.index("name");
// 查询所有 name = "Alice" 的记录
index.getAll("Alice").onsuccess = (e) => console.log(e.target.result);

除了 getAll(),IndexedDB 的索引对象还提供了其他几种常用的查询方法,以应对不同的业务场景:

方法说明返回值
index.get(value)获取匹配该索引值的第一条记录单个对象或undefined
index.getAll(value)获取匹配该索引值的所有记录数组[]
index.getAllKeys(value)获取匹配该索引值的所有主键主键数组[]
index.count(value)统计匹配该索引值的记录数量数字Number

注意:

事务上下文:在执行 store.get() 或 store.index() 之前,请确保当前处于一个有效的 readwrite 或 readonly 事务(Transaction)中。如果事务已经结束或发生错误,调用这些方法会抛出异常。
索引必须提前创建:store.index("name") 中的 "name" 必须在数据库初始化(onupgradeneeded)时通过 objectStore.createIndex('name', 'name', { unique: false }) 创建过,否则会报错。
分批提交:单次事务写入 500~2000 条,避免长时间阻塞。
主动让出主线程:用 queueMicrotask 或 setTimeout 间隔执行批次。

1.5 典型应用场景

1)离线优先应用(PWA)

离线数据持久化:用户操作实时存入 IndexedDB,网络恢复后同步至服务器。
配合 Service Worker:缓存静态资源(Cache API),IndexedDB 存储动态数据,实现完整离线体验。

2)大数据量客户端缓存

结构化数据缓存:商品目录、用户历史记录等 >100KB 的数据,避免频繁请求服务器。
性能敏感场景:对比测试显示,2 万条商品数据(约 4.8MB)的读写,IndexedDB 比 localStorage 快 3.8~6.3 倍,索引查询效率提升 ≥16 倍。

3)二进制资源管理

图片/文档本地缓存:存储 Blob 数据,实现“秒开”体验(如文档查看器、图片库)。
游戏状态保存:关卡进度、玩家属性等需结构化存储的场景。

1.6 使用注意事项与最佳实践

1)工程化设计原则

按业务域拆分仓库:避免将用户配置、日志、临时数据混存于同一对象仓库。
索引精简化:仅高频查询字段建索引,长文本字段(如:content)不适合索引,全文检索应交由专用库(如:FlexSearch)。

2)容量与清理策略

主动监控配额:通过 navigator.storage.estimate() 检测用量,当 usage/quota > 0.8 时触发清理。
分级清理机制:优先删除带 expiresAt 的临时数据(如:日志),再清理旧快照,避免误删核心数据。

3)隐私与安全

敏感数据加密:IndexedDB 本身 无内置加密,存储密码等信息需先通过 Web Crypto API 加密。
隐身模式限制:数据仅内存驻留,关闭窗口即销毁,不可依赖其持久化能力。

回到顶部

二、什么是 Cache storage?

2.1 简介

Cache Storage 是浏览器提供的专用于缓存网络请求/响应对(Request/Response)的持久化存储机制,由开发者通过 JavaScript 显式控制,独立于 HTTP 缓存头,主要用于实现离线优先的 Web 应用(如:PWA)。

其核心价值在于完全自主管理资源缓存策略(如:离线访问、网络回退),而非依赖服务器设置的缓存规则。

Cache Storage将缓存控制权交给开发者,使其能精准实现离线场景需求。

实际使用时,应避免将其视为“自动缓存”工具——所有缓存操作必须显式编码,且需严格管理生命周期。

对于简单场景,可结合 workbox 等库简化策略实现;若仅需缓存静态资源,优先通过 HTTP 头配置强缓存,而非过度依赖 Cache Storage。

Cache Storage 是 W3C Service Workers 规范的一部分,但 不限于 Service Worker 环境,也可在主线程通过 caches 全局对象访问。它专为存储HTTP 请求-响应对设计,直接缓存二进制资源(如:HTML、CSS、JS、图片),而非结构化数据(后者应使用 IndexedDB)。

Cache Storage 与 HTTP 缓存的关键区别:

对比维度HTTP 缓存Cache Storage
控制权归属由服务器通过Cache-Control/Expires响应头控制。完全由开发者通过代码管理,忽略 HTTP 缓存头。
缓存粒度基于 URL 和响应头自动生效。需显式调用 API 添加/匹配资源,支持自定义匹配逻辑(如:忽略查询参数)。
适用场景适用于常规页面加载加速。专为离线场景设计(如:PWA 的离线资源预加载)。

2.2 核心特性与限制

1)关键能力

持久化存储:缓存数据跨页面刷新和浏览器会话保留,除非开发者主动删除。
独立于网络请求:可通过 caches.match(request) 手动检查缓存,无需实际发起网络请求。
灵活匹配策略:支持自定义匹配逻辑(如:忽略 URL 查询参数),通过 Cache.match(request, options) 的 options 参数控制。

2)重要限制

仅支持 GET 请求:Cache.add()/addAll()/put() 无法缓存 POST 等非安全请求。
HTTPS 强制要求:生产环境中必须通过 HTTPS 服务(本地开发可使用 http://localhost),否则 API 调用会抛出 SecurityError。
存储空间受配额约束:浏览器对单域名缓存总量有上限(通常为设备空闲磁盘的 50%~60%),需通过 navigator.storage.estimate() 监控用量。

2.3 核心 API 与工作流程

基础操作方法有:

方法作用
caches.open(cacheName)打开指定名称的缓存仓库,若不存在则自动创建。
cache.addAll(urls)批量缓存资源列表,任一失败则全部回滚。
cache.put(request, response)手动存入请求-响应对(常用于动态缓存)。
caches.match(request)跨所有缓存仓库匹配请求,返回首个匹配的响应。
cache.keys()获取当前缓存仓库中所有请求的列表。

典型工作流程(Service Worker 场景)

1)安装阶段预缓存资源

self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then(cache =>
cache.addAll(['/index.html', '/style.css', '/app.js'])
)
);
});
// 关键点:通过 waitUntil 确保缓存完成前 Service Worker 不进入激活状态

2)拦截请求并返回缓存

self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cachedResponse =>
cachedResponse || fetch(event.request) // 无缓存则走网络
)
);
});
// 扩展策略:可实现 cache-first(优先缓存)、network-first(优先网络)等混合策略

2.4 典型应用场景

1)PWA 离线资源管理

预加载核心资源:在安装阶段缓存 Shell(HTML/CSS/JS),确保 首次加载后完全离线可用。
动态资源缓存:用户访问时缓存图片/数据,后续离线时仍可查看历史内容。

2)自定义缓存策略

忽略查询参数:通过 new Request(url, { ignoreSearch: true }) 匹配忽略 ?v=1.2.3 的资源。
版本化缓存:按版本号命名缓存仓库(如:app-v2),旧版本缓存需手动清理,避免空间浪费。

3)网络优化

降级体验保障:网络请求失败时返回缓存内容(stale-while-revalidate 模式)。
减少重复请求:对静态资源(如:字体、第三方库)实现跨页面/会话的持久缓存。

相关新闻

  • 网易云音乐自动打卡神器:每天300首轻松升级LV10的完整实用指南
  • Jetpack Compose 入门指南
  • MSPM0定时器实战:QEI编码器解码与PWM电机控制全解析

最新新闻

  • ChatGPT Go客户端安全加固手册:TLS双向认证、token轮换、审计日志全覆盖(附可审计代码模板)
  • 如何深度掌控AMD Ryzen处理器:SMU Debug Tool完整指南
  • 免费解锁WeMod专业版:Wand-Enhancer完全使用指南
  • Simcenter STAR-CCM+安装步骤(附安装包)STAR-CCM+ 超详细下载安装教程
  • 人工智能大模型兵棋推演系统软件平台:有哪些优点和缺点
  • BurpSuite 2023+ 上游代理配置实战:告别UserOptions,拥抱Settings新路径

日新闻

  • ENVI5.3.1实战:基于Landsat 8影像的区域无缝镶嵌与精准裁剪
  • 3步完成HS2-HF Patch安装:新手快速打造完美HoneySelect2体验
  • 微信好友检测终极指南:3分钟发现谁已悄悄删除你

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号