使用localStorage存储大量对象的最佳实践

11

目前,我正在使用localStorage来存储大量相同类型的对象,并且有些困惑。

一种思路是将所有对象存储在数组中。但是对于每个单独对象的读/写操作,都需要反序列化/序列化整个数组。

另一种方式是直接将每个对象及其关键字存储在localStorage中。这将使访问每个对象更加容易,但我担心将要存储的对象数量(数万个)。此外,获取所有对象将需要迭代整个localStorage!

请问您有哪些经验可以分享,哪种方式更好?此外,是否值得尝试更复杂的客户端数据库,如PouchDB?


你的项目是否有可能离线收集超过5MB的数据? 如果是这样,那么你肯定需要PouchDB以及它的WebSQL和IndexedDB适配器(同时还有localStorage选项供非常老的浏览器使用)。 - Angel Paraskov
我知道localstorage有5MB的限制,目前为止还好,所以我不太担心它。PouchDB是一个100k+的依赖项,如果没有必要,我不想添加它。 - Wudong
如果空间不是问题,为什么不使用PouchDB呢?这样可以避免烦恼如何存储数据以及如何进行后期更新。让PouchDB API来代替你处理这些问题。此外,它还支持类似CouchDB的map/reduce,甚至可以使用SQL、GQL和Mongo插件编写查询语句。祝好运! - Angel Paraskov
PouchDB的最小+gz文件大小约为50KB,而LocalForage的大小约为20KB。 :) - nlawson
3个回答

4
如果你想要一个简单的存储大量键值对的工具,并且不想担心类型问题,我推荐使用LocalForage。你可以存储字符串、数字、数组、对象、Blob等任何内容。它使用IndexedDB和WebSQL(如果可用),所以存储限制比LocalStorage高得多。
PouchDB也可以使用,但API更加复杂,适合在需要与服务器上的CouchDB同步数据时使用。

3
如果您不想拥有很多密钥,可以采取以下两种方法之一:
  • 将行JSON串通过\n连接在一起,并将它们作为单个键存储。
  • 构建并更新索引,索引存储在单独的键下,每个索引链接某个键和特定的行号。
在这种情况下,解析行数据只需要使用 .split('\n') ,比使用JSON.parse快了两个数量级。
请注意,在同时打开多个选项卡时,您可能需要特别努力来同步。在复杂的情况下,这可能是一个挑战。 localStorage 有好的地方也有坏的地方。
好处:
  • 同步性强;
  • 速度极快,读写都相当于memcpy – 即使在弱设备上,也能达到100+Mb/s的吞吐量(例如,JSON.stringify通常比localStorage.setItem慢5-20倍);
  • 经过彻底测试和可靠。
坏消息:
  • 没有事务处理,因此需要工程师的努力来同步选项卡;
  • 假设您最多没有超过2Mb(因为存在此限制的系统);
  • 实际上存储2Mb仅意味着您可以保存1M字符。
这些要点显示了 localStorage 作为数据库应用的边界。LS适用于需要同步性和速度的任务,并且您可以削减数据库以适应配额。
因此,localStorage 适用于缓存和日志记录。没有更多了。

这个答案对我来说非常有趣,但是我希望有一个代码示例,因为我对这个想法有点困惑。 - thinktt
@thinktt 具体是哪个想法? - ermouth
我认为经过更多的思考,我开始理解了,但是这个想法是: "1. 将行JSON与\n连接起来,并将它们作为单个键存储 2. 构建和更新存储在单独键下的索引,每个索引将某个键与特定行号链接" 你能给出一个简短的代码示例吗? - thinktt
抱歉,我不能。 - ermouth

1

我个人没有使用过localStorage来管理这么多元素。

然而,我通常用来管理数据的模式是将完整的信息数据库加载到JavaScript对象中,在处理过程中在内存中进行管理,并在处理完成后再次保存到localStorage中。

当然,这种模式可能不是您的需求的好方法,这取决于您的项目规格。

如果您需要不断保存数据,数据访问可能会成为一个问题,因此可能使用某种类型的小型数据库访问是更好的选择。

如果您的数据量异常大,将其管理在内存中也可能成为一个问题,但是,根据数据模型,您可以构建有效的结构,使您能够在需要时仅加载和保存数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接