【问题标题】:How much space does the localstorage key itself take up?localstorage key 本身占用多少空间?
【发布时间】:2015-04-30 00:22:50
【问题描述】:

假设我创建了一个本地存储密钥并给它一个空字符串。 keyitem 的名称占用的空间是否与每个字符的值占用的空间相同?

比如

localStorage.setItem("keyitem","") 
//Equal the space of this other one under?
localStorage.setItem("key","item");

另外,密钥的数量是否重要?比如

localStorage.setItem("key","");
//Equal the amount of storage as the 3 under combined? 
localStorage.setItem("k","");
localStorage.setItem("o","");
localStorage.setItem("h","");

【问题讨论】:

  • 密钥的数量几乎是二进制的 - 01。不能有多个同名键,多次调用setItem 只是覆盖之前的值。
  • 这是特定于浏览器的,因为每个浏览器以不同方式存储其数据,即 chrome/firefox 我相信使用 sqlite dbs、opera xml 文件
  • 请记住,这可能正是浏览器想要做的。我猜它会将 16 或 32 位字符串存储为键和值。但我不确定。 (浏览器想用它做什么:他们以不同的方式实现它,probs)
  • 我编辑了不同的关键项

标签: javascript html local-storage


【解决方案1】:

我曾经找到一个函数来计算 localStoragesessionStorage 对象的大小,但我不记得在哪里找到它了。

代码如下:

Storage.prototype.size = function(units) {
    'use strict';
    units = units ? units.toUpperCase() : 'MB';
    var size = unescape(encodeURIComponent(JSON.stringify(this))).length;
    switch (units) {
        case 'B': return [size,'B'].join(' ');
        case 'KB': return [+(size / 1024).toFixed(3),'KB'].join(' ');
        default: return [+(size / 1024 / 1024).toFixed(3),'MB'].join(' ');
    }
};

我决定继续在各种浏览器中运行一些测试。

火狐(37.0.2):

铬(42.0.2311.90 m):

IE 11 (11.0.9600.17420):

歌剧(29.0.1795.47):

所以看起来 FireFox、Chrome 和 Opera(可能还有 Safari,但我没有)都具有相同的行为,并且键占用的空间远远超过其值。

在 IE(好老的 IE...)中,实现的执行方式与存储方式无关。

【讨论】:

  • 我将在稍后的回答中引用一条评论:“这并没有显示实际密钥占用了多少空间。这只是显示了 localStorage 的 JSON 表示的字符数量。每个浏览器都实现了它自己的数据保存方式。这些方法中的每一种都可以完全不同地存储数据。例如,一种可能使用 utf8 编码,而另一种可能使用 utf16(即使用 2 个字节表示 1 个字符),有些可能使用压缩等——帕特里克·埃文斯”。这也适用于您的方法——您只需测量 JSON 字符串。 (ctd)
  • (ctd) IE 的实现与这里并没有什么不同。问题在于密钥key——在大多数实现中,它不包括JSON 表示。显然 IE 在这种情况下确实包含它。因此,您将获得 JSON {"keyitem":""},第一个为 14 个字节,第二个为 {}。在 IE 中,第二个是 {"key":"item"}。所以你不能从这里真正分辨出来。 -1
  • @Scimonster 我将引用对您引用的评论的回应:“我同意,但这是了解本地存储中存储内容的最佳代理。- Jaco de Groot”
【解决方案2】:

keyitem 的名称是否占用与 每个字符的价值?

不,没有必要。键占用的空间量可能大于值占用的空间量。但是键和值占用的空间应该是大约 5MB(虽然这与浏览器不同,因为它取决于浏览器

您可以使用此代码进行测试:

localStorage.clear();
localStorage.setItem(new Array(5e6).join(' '),'');
localStorage.key(0).length;

上述测试在 Chrome 上的输出:

只要comes under 5MB(which is mostly the upper limit for most browsers) 你的密钥可以有任意长度

【讨论】:

  • 另外提到 5MB 等于 Chrome 上的 250 万个字符。还有这个:stackoverflow.com/questions/11333807/…
  • @Rahil Tripathi 在这种情况下你会说 5MB 也等于 250 万 localStorage.setItem("h","");也只包含一个字符?
  • @mattias:- 不,这是上限(这也是特定于浏览器的)。您可以运行我在浏览器中添加的测试(在 Firefox 中为我制作了大约 2.94MB),您将获得密钥占用的空间。如果您将密钥用作“k”,则它不是 5MB。现在有意义吗?
  • @mattias:- 所以如果你想检查localStorage.setItem("kgfdshfgsdhfdksfd.........2.5million characters",""); 你会发现Chrome的空间至少接近5MB
  • 好吧,答案是我认为键与值本身占用相等的空间,看不到你添加的测试?它应该是哪个链接?是的,它的上限值不同,但我的意思是,如果有 250 万个不同的本地存储键,只有一个字符作为键名,那是否等于一个键名为 250 万个字符的键?
【解决方案3】:

您可以自己确定这一点,方法是使用 JSON stringify 方法将 localStorage 对象转换为 JSON 对象:

JSON.stringify(localStorage).length

这不会返回密钥的实际大小,因为数据可以存储为 utf16(2 个字节)或 utf8(1 个字节),但它是实际大小的一个很好的代理。见下面的代码sn-p:

 localStorage.clear()
 localStorage.setItem("keyitem","") 
 document.write(JSON.stringify(localStorage).length+'</br>')

 //Equal the space of this other one under?
 localStorage.setItem("key","item");
 document.write(JSON.stringify(localStorage).length+'</br>')

 localStorage.clear();
 localStorage.setItem("key","");
 document.write(JSON.stringify(localStorage).length+'</br>')


 //Equal the amount of storage as the 3 under combined? 
 localStorage.setItem("k","");
 localStorage.setItem("o","");
 localStorage.setItem("h","");
 document.write(JSON.stringify(localStorage).length+'</br>')

【讨论】:

  • 所以您是说所有浏览器都将其存储为 JSON 字符串?我想这是有道理的,因为它是 Javascript 对象表示法,但你怎么知道?我有兴趣
  • 你的答案是什么?我不知道您在 jsFiddle 中确定了什么,并且 jsFiddle 现在没有为我加载。这就是为什么我们将所有重要的细节都直接放在这里而不是放在其他一些糟糕的网站上。
  • 抱歉,这段代码 sn-p 不适用于 StackOverflow 本身。
  • 这并不显示实际密钥占用了多少空间。这只是显示了 localStorage 的 JSON 表示的字符数量。每个浏览器都实现了自己的数据保存方式。这些方法中的每一个都可以完全不同地存储数据。例如,一个可能使用 utf8 编码,而另一个可能使用 utf16(意味着使用 2 个字节表示 1 个字符),有些可能使用压缩等。
  • 我同意,但它是了解 localStorage 中存储内容的最佳代理。
【解决方案4】:

我想说这是关于磁盘上存储的真实结构的实现细节。

在实践中,每个源都为您提供一定的空间(通常为 5MiB,要检查实际存储,您可以使用 MDN 文档中链接的 test tool)并且您可以存储数据(以键和值的形式) ) 只要您不超过该大小,如上一个答案所示。所以是的keys are included in the storage quota

正如我在包含的测试工具中指出的那样,字符实际上是 UTF-16,因此它们占用了 2 个字节的存储配额。

还请注意,存储存储字符串,这意味着如果您将大浮点数作为键或值,您不是将其存储为二进制格式,而是作为字符串!

// These takes up the same space
localStorage.setItem("a", 123);
localStorage.setItem("a", "123");

事实上,如果您尝试执行以下类型的操作,两种情况都会得到 string

localStorage.setItem("123", "");
localStorage.setItem(123, "");
typeof localStorage.key(0); // returns "string"
typeof localStorage.key(1); // returns "string" as well

至于第二部分,在存储方面这个

localStorage.setItem("k","");
localStorage.setItem("o","");
localStorage.setItem("h","");

应该从您的配额中占用 3 个字符的存储空间,如果使用 UTF-16,则为 3 * 2 字节,如果使用 UTF-8,则为 3 字节。

有关本地存储解决方案的概述,您可以在此处查看http://www.html5rocks.com/en/features/storage

【讨论】:

    【解决方案5】:

    我在 Chrome 中进行了测试,并能够证明密钥占用的空间与长度完全相同。

    使用abc 的键,我可以设置长度为5242877 的值。使用a 的键,我可以设置长度为5242879 的值。如您所见,从key 释放了这 2 个值。

    【讨论】:

    • 好的,太好了! “如果有 250 万个(例如)不同的本地存储键,只有一个字符作为键名,这是否等于一个键名为 250 万个字符的键?”
    • 是的,好像是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多