前端缓存localStage和IndexDB

76 阅读3分钟

localStorage在JavaScript中是同步的。当你调用localStorage.setItem()localStorage.getItem()时,操作会立即执行,并且会阻塞其他JavaScript代码的执行,直到操作完成。这意味着,如果你正在进行一个耗时的localStorage操作,可能会导致浏览器的用户界面暂时无响应。

存储位置

localStorage 是 Web Storage API 的一部分,它提供了一种存储键值对的机制。localStorage 的数据是持久存储在用户的硬盘上的,而不是内存。这意味着即使用户关闭浏览器或电脑,localStorage 中的数据也不会丢失,除非主动清除浏览器缓存或者使用代码删除。

当你通过 JavaScript 访问 localStorage 时,浏览器会从硬盘中读取数据或向硬盘写入数据。然而,在读写操作期间,数据可能会被暂时存放在内存中,以提高处理速度。但主要的特点是它的持久性,以及它不依赖于会话的持续性

硬盘是一个IO设备,大部分与硬盘相关的操作系统级IO操作确实是异步进行的,以避免阻塞进程,不过,在web浏览器环境中,localStorage的API是设计为同步的,即使底层的硬盘读写操作有着IO的特性。

js代码在访问localStorage时,浏览器提供的API接口通常会处于js执行线程上下文中直接调用,这意味着尽管硬盘是IO设备,当一个js执行流程访问localStorage时,他会同步等待数据读取或写入完成,该过程中js执行线程会阻塞。

执行流程

  • js线程调用: 执行localStorage getItem或者setItem操作,这个调用发生在js的单线程上;

  • 浏览器引擎处理:浏览器的js引擎接收到调用请求后,会向浏览器的存储子系统发出同步IO请求,js引擎等待IO操作的完成

  • 文件系统的同步IO: 浏览器存储子系统对硬盘执行实际的存储或检索操作。尽管操作系统层面可能对文件访问进行缓存或优化,但从浏览器的角度看,它会进行一个同步的文件系统操作,直到这个操作返回结果。

  • 操作完成返回: 一旦IO操作完成,数据要么被写入硬盘,要么被从硬盘读取出来,浏览器存储子系统会将结果返回给 js 引擎。

  • JavaScript线程继续执行: js 引擎在接收到操作完成的信号后,才会继续执行下一条 js 代码。

localStorage限制容量是因为同步阻塞吗?

  1. 资源公平分享,防止单个网站消耗大量本地资源
  2. 防止滥用:存储大量数据在用户设备上,会导致设备资源空间迅速耗尽
  3. 性能限制:同步阻塞,影响页面性能
  4. 存储效率:存储数据大,会降低效率
  5. 历史和兼容性:5MB被大部分浏览器实现和采纳
  6. 浏览器政策

IndexedDB

IndexedDB 是一种在用户浏览器内持久化存储数据的方法。它可以让你创建具有丰富查询能力的 Web 应用,而无需考虑网络可用性,因此你的应用在在线和离线时都可以正常运行。

对比localStorageIndexDB
存储容量5MB可以达到几百MB甚至更高,具体取决于用户的硬盘空间和浏览器的策略
数据类型字符串,非字符串需转换成字符串可以直接存储多种数据类型,包括对象、数组、字符串、日期等。
异步 vs 同步同步异步
查询能力提供了非常基础的键值对存储,没有查询语言提供了更复杂的查询能力,包括索引、游标和事务。
浏览器支持现代浏览器兼容性好部分浏览器不兼容

参考:juejin.cn/post/735940…
MDN: developer.mozilla.org/zh-CN/docs/…