基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

IndexedDB 是什么?它适用于什么场景?

知识点图片

IndexedDB 是浏览器提供的一种底层 API,用于在客户端(用户的浏览器)存储大量的结构化数据(包括文件/二进制大对象 Blobs)。

简单来说,你可以把它理解为浏览器内置的一个非关系型数据库(NoSQL Database)

以下是关于它的详细介绍和适用场景:


一、 IndexedDB 是什么?(核心特性)

与 LocalStorage 或 Cookie 不同,IndexedDB 功能更强大,主要特点如下:

  1. 存储容量大
    • LocalStorage 通常限制在 5MB - 10MB。
    • IndexedDB 的容量通常取决于用户磁盘剩余空间(通常可以达到几百 MB 甚至 GB 级别)。
  2. 键值对存储(Key-Value)
    • 它是一个对象仓库(Object Store)。
    • 不同于 LocalStorage 只能存字符串,IndexedDB 可以直接存储 JavaScript 对象数组,甚至 二进制数据(ArrayBuffer, Blob, File)。
  3. 异步操作(Asynchronous)
    • IndexedDB 的操作(读写)不会阻塞浏览器的主线程。这意味着在读写大量数据时,页面不会“卡顿”。
    • 相比之下,LocalStorage 是同步的,数据量大时会阻塞页面渲染。
  4. 支持事务(Transactional)
    • 这意味着一系列操作要么全部成功,要么全部失败(回滚),保证了数据的一致性。
  5. 支持索引(Indexing)
    • 你可以给存储的对象属性建立索引,从而实现高性能的搜索和查询。
  6. 同源策略
    • 和 Cookie、LocalStorage 一样,IndexedDB 受同源策略限制,网页只能访问自身域名下的数据库。

二、 IndexedDB 适用于什么场景?

由于其大容量和异步特性,IndexedDB 非常适合以下场景:

1. 离线应用(Offline First / PWA)

这是 IndexedDB 最核心的用途。

  • 场景:用户在没有网络(如在地铁、飞机上)时,依然可以使用网页应用。
  • 做法:将 API 返回的数据、文章内容、图片等缓存在 IndexedDB 中。当网络断开时,从 IndexedDB 读取数据展示;当网络恢复时,再与服务器同步。

2. 存储大量结构化数据

  • 场景:电商网站的商品目录、复杂的 CMS 系统、管理后台的大量表格数据。
  • 做法:如果数据量超过 5MB,或者数据结构复杂(嵌套对象),LocalStorage 无法胜任,必须使用 IndexedDB。

3. 存储文件和二进制数据

  • 场景:在线图片编辑器、音频/视频处理应用、网盘类应用。
  • 做法:用户上传的图片、生成的 PDF、录制的音频可以直接以 BlobFile 对象的形式存入 IndexedDB,无需转换成 Base64 字符串(Base64 会增加体积且处理慢)。

4. 客户端缓存(提升性能)

  • 场景:数据分析大屏、地图应用。
  • 做法:有些静态资源或很少变动的 API 数据(如城市列表、字典表),每次都从服务器拉取很浪费带宽。可以将其持久化存储在 IndexedDB 中,极大提升二次加载速度。

5. 复杂的应用状态管理

  • 场景:类似 Figma、Notion 这样复杂的 Web 应用。
  • 做法:用户的每一步操作历史(用于撤销/重做)、草稿内容都需要实时保存。IndexedDB 的事务和异步特性可以保证在频繁自动保存时不仅数据安全,还不会卡顿界面。

三、 IndexedDB 与 LocalStorage 的简单对比

特性 LocalStorage IndexedDB
容量 小 (约 5MB) 大 (> 250MB,视磁盘而定)
数据类型 仅字符串 (String) JS对象、文件、二进制、数组等
操作方式 同步 (阻塞主线程) 异步 (不阻塞)
查询能力 只能按 Key 取值 支持索引,可按属性查询
上手难度 极简 较复杂 (原生 API 繁琐)

四、 开发建议

虽然 IndexedDB 很强大,但它的原生 API 设计得比较古老且繁琐(基于事件监听,容易写出回调地狱)。

在实际开发中,强烈建议使用封装库,它们提供了更现代的 Promise/Async-Await 语法:

  1. Dexie.js (最推荐):功能强大,语法优雅,支持 TypeScript,社区活跃。
  2. localForage:API 极其简单(类似 LocalStorage 的 getItem/setItem),底层自动降级(如果不支持 IndexedDB 则回退到 WebSQL 或 LocalStorage)。
  3. idb:一个轻量级的库,主要将 IndexedDB 包装成 Promise 形式。

总结:
如果你只需要存个 Token 或简单的用户配置,用 LocalStorage
如果你需要开发离线应用、存图片/文件、或者缓存大量数据,IndexedDB 是唯一的选择。

00:00
00:00