如何查找 localStorage 的大小

我目前正在开发一个网站,将利用 HTML5的 localStorage。我已经阅读了所有关于不同浏览器的大小限制。但是,我还没有看到任何关于如何查找 localStorage 实例的当前大小的内容。这个问题似乎表明 JavaScript 没有内置的方式来显示给定变量的大小。LocalStorage 是否有我没有看到的内存大小属性?有没有什么简单的办法能解决我的问题?

我的网站是为了允许用户在“离线”模式下输入信息,所以能够在存储器几乎满时给他们一个警告是非常重要的。

111282 次浏览
window.localStorage.remainingSpace

IE 具有 Storage 对象的 剩余空间属性。其他浏览器此时没有相应的属性。

我相信默认的空间大小是5MB,尽管我没有亲自测试过。

下面是一个简单的 例子,告诉你如何做到这一点,并且应该与每个浏览器一起工作

alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);

按照规范,字符串的每个字符都是16位。

但是使用 chrome (Settings > Content Settings > Cookies & Site data)进行检查会发现启动 localStorage 需要3kB (开销大小)

存储的数据大小遵循这个关系(精确到1kB)
3 + ((localStorage.x.length * 16)/(8 * 1024)) kB < br >

其中 localStorage.x 是存储字符串。

在 JavaScript 控制台中执行这段代码片段(一行版本) :

var _lsTotal=0,_xLen,_x;for(_x in localStorage){ if(!localStorage.hasOwnProperty(_x)){continue;} _xLen= ((localStorage[_x].length + _x.length)* 2);_lsTotal+=_xLen; console.log(_x.substr(0,50)+" = "+ (_xLen/1024).toFixed(2)+" KB")};console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");




为了便于阅读,在多行中使用了相同的代码

var _lsTotal = 0,
_xLen, _x;
for (_x in localStorage) {
if (!localStorage.hasOwnProperty(_x)) {
continue;
}
_xLen = ((localStorage[_x].length + _x.length) * 2);
_lsTotal += _xLen;
console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB")
};
console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");

或在书签的“位置”栏中添加此文本,以方便使用

javascript: var x, xLen, log=[],total=0;for (x in localStorage){if(!localStorage.hasOwnProperty(x)){continue;} xLen =  ((localStorage[x].length * 2 + x.length * 2)/1024); log.push(x.substr(0,30) + " = " +  xLen.toFixed(2) + " KB"); total+= xLen}; if (total > 1024){log.unshift("Total = " + (total/1024).toFixed(2)+ " MB");}else{log.unshift("Total = " + total.toFixed(2)+ " KB");}; alert(log.join("\n"));

附注: 代码片段会根据注释中的请求进行更新。现在计算包括密钥本身的长度。 每个长度乘以2,因为 javascript 中的 char 存储为 UTF-16(占用2个字节)

P.P.S. 应该可以同时在 Chrome 和 Firefox 中使用。

希望这能帮到别人。

因为 jsfiddle 上的 Jas-example 不适合我,所以我想出了这个解决方案。 (感谢 Serge Seletsky 和 Shourav 在下面的代码中提供的信息)

下面的函数可以用来测试 localStorage 有多少空间可用,以及(如果 lS 中已经有任何键)还剩下多少空间。

虽然有点粗暴,但是几乎所有的浏览器都可以使用,除了 Firefox。 在桌面 FF 中需要花费很长时间(4-5分钟)才能完成,而在 Android 上它只会崩溃。

在这个函数的下面是一个简短的测试总结,我已经在不同的浏览器上在不同的平台上完成!

function testLocalStorage() {
var timeStart = Date.now();
var timeEnd, countKey, countValue, amountLeft, itemLength;
var occupied = leftCount = 3; //Shurav's comment on initial overhead
//create localStorage entries until localStorage is totally filled and browser issues a warning.
var i = 0;
while (!error) {
try {
//length of the 'value' was picked to be a compromise between speed and accuracy,
// the longer the 'value' the quicker script and result less accurate. This one is around 2Kb
localStorage.setItem('testKey' + i, '11111111112222222222333333333344444444445555555555666661111111111222222222233333333334444444444555555555566666');
} catch (e) {
var error = e;
}
i++;
}
//if the warning was issued - localStorage is full.
if (error) {
//iterate through all keys and values to count their length
for (var i = 0; i < localStorage.length; i++) {
countKey = localStorage.key(i);
countValue = localStorage.getItem(localStorage.key(i));
itemLength = countKey.length + countValue.length;
//if the key is one of our 'test' keys count it separately
if (countKey.indexOf("testKey") !== -1) {
leftCount = leftCount + itemLength;
}
//count all keys and their values
occupied = occupied + itemLength;
}
;
//all keys + values lenght recalculated to Mb
occupied = (((occupied * 16) / (8 * 1024)) / 1024).toFixed(2);
//if there are any other keys then our 'testKeys' it will show how much localStorage is left
amountLeft = occupied - (((leftCount * 16) / (8 * 1024)) / 1024).toFixed(2);
//iterate through all localStorage keys and remove 'testKeys'
Object.keys(localStorage).forEach(function(key) {
if (key.indexOf("testKey") !== -1) {
localStorage.removeItem(key);
}
});


}
//calculate execution time
var timeEnd = Date.now();
var time = timeEnd - timeStart;
//create message
var message = 'Finished in: ' + time + 'ms \n total localStorage: ' + occupied + 'Mb \n localStorage left: ' + amountLeft + "Mb";
//put the message on the screen
document.getElementById('scene').innerText = message; //this works with Chrome,Safari, Opera, IE
//document.getElementById('scene').textContent = message;  //Required for Firefox to show messages
}

正如上面所承诺的,在不同的浏览器中进行一些测试:

Galaxy Tab 10.1

  • Maxthon Pad 1.7 ~ 1130ms 5Mb
  • Firefox 20.0(Beta 20.0)两者都崩溃了
  • Chrome 25.0.1364.169 ~ 22250ms/5Mb
  • 原生(标识为 Safari 4.0/Webkit534.30) ~ 995ms/5Mb

IPhone4s iOS6.1.3

  • Safari ~ 520ms/5Mb
  • 作为 HomeApp ~ 525ms/5Mb
  • ICab ~ 710ms/5mb

MacBook Pro OSX 1.8.3(Core 2 Duo 2.668Gb 内存)

  • Safari 6.0.3 ~ 105ms/5Mb
  • Chrome 26.0.1410.43 ~ 3400ms/5Mb
  • Firefox 20.0300150ms (!)/10Mb (在抱怨脚本运行过长之后)

IPad3 iOS6.1.3

  • Safari ~ 430ms/5Mb
  • ICab ~ 595ms/5mb

Windows 7-64b (Core 2 Duo 2.936Gb 内存)

  • Safari 5.1.7 ~ 80ms/5Mb
  • Chrome 26.0.1410.43 ~ 1220ms/5Mb
  • Firefox 20.0228500ms (!)/10Mb (在抱怨脚本运行过长之后)
  • IE9 ~ 17900ms/9.54 Mb (如果代码中有 console.log,那么在 DevTools 打开之前它不能工作)
  • Opera 12.15 ~ 4212ms/3.55 Mb (这时选择了5Mb,但 Opera 很友好地询问我们是否要增加 lS 的数量,不幸的是,如果连续进行几次测试,它就会崩溃)

胜8(平行下8)

  • IE10 ~ 7850ms/9.54 Mb

基于@Shourav 上面所说的,我编写了一个小函数,它可以准确地获取所有的 localStorage键(针对当前域) ,并计算合并后的大小,这样你就可以准确地知道 localStorage对象占用了多少内存:

var localStorageSpace = function(){
var allStrings = '';
for(var key in window.localStorage){
if(window.localStorage.hasOwnProperty(key)){
allStrings += window.localStorage[key];
}
}
return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
};

我的返回: "30.896484375 KB"

您可以通过以下方法计算您的本地存储:

function sizeofAllStorage(){  // provide the size in bytes of the data currently stored
var size = 0;
for (i=0; i<=localStorage.length-1; i++)
{
key = localStorage.key(i);
size += lengthInUtf8Bytes(localStorage.getItem(key));
}
return size;
}


function lengthInUtf8Bytes(str) {
// Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
var m = encodeURIComponent(str).match(/%[89ABab]/g);
return str.length + (m ? m.length : 0);
}


console.log(sizeofAllStorage());

最后,以字节为单位的大小将记录在浏览器中。

我会使用@tennisgen 的代码来获取所有内容并计算内容,但我会自己计算密钥:

var localStorageSpace = function(){
var allStrings = '';
for(var key in window.localStorage){
allStrings += key;
if(window.localStorage.hasOwnProperty(key)){
allStrings += window.localStorage[key];
}
}
return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
};

除了@serge 的答案是这里投票最多的,还需要考虑密钥的大小。下面的代码将添加存储在 localStorage中的密钥的大小

var t = 0;
for (var x in localStorage) {
t += (x.length + localStorage[x].length) * 2;
}
console.log((t / 1024) + " KB");

//同时占用键和值的内存,因此更新了代码。

var jsonarr=[];
var jobj=null;
for(x in sessionStorage) // Iterate through each session key
{
jobj={};
jobj[x]=sessionStorage.getItem(x); //because key will also occupy some memory
jsonarr.push(jobj);
jobj=null;
}
//https://developer.mozilla.org/en/docs/Web/JavaScript/Data_structures
//JavaScript's String type is used to represent textual data. It is a set of "elements" of 16-bit unsigned integer values.
var size=JSON.stringify(jsonarr).length*2; //16-bit that's why multiply by 2
var arr=["bytes","KB","MB","GB","TB"]; // Define Units
var sizeUnit=0;
while(size>1024){ // To get result in Proper Unit
sizeUnit++;
size/=1024;
}
alert(size.toFixed(2)+" "+arr[sizeUnit]);

我解决这个问题的方法是创建函数来查找本地存储中使用的空间和剩余空间,然后创建一个函数来调用这些函数来确定最大存储空间。

function getUsedSpaceOfLocalStorageInBytes() {
// Returns the total number of used space (in Bytes) of the Local Storage
var b = 0;
for (var key in window.localStorage) {
if (window.localStorage.hasOwnProperty(key)) {
b += key.length + localStorage.getItem(key).length;
}
}
return b;
}


function getUnusedSpaceOfLocalStorageInBytes() {
var maxByteSize = 10485760; // 10MB
var minByteSize = 0;
var tryByteSize = 0;
var testQuotaKey = 'testQuota';
var timeout = 20000;
var startTime = new Date().getTime();
var unusedSpace = 0;
do {
runtime = new Date().getTime() - startTime;
try {
tryByteSize = Math.floor((maxByteSize + minByteSize) / 2);
//localStorage.setItem(testQuotaKey, new Array(tryByteSize).join('1'));
            

//Recommended by @pkExec and @jrob007
localStorage.setItem(testQuotaKey, String('1').repeat(tryByteSize));
minByteSize = tryByteSize;
} catch (e) {
maxByteSize = tryByteSize - 1;
}
} while ((maxByteSize - minByteSize > 1) && runtime < timeout);


localStorage.removeItem(testQuotaKey);


if (runtime >= timeout) {
console.log("Unused space calculation may be off due to timeout.");
}


// Compensate for the byte size of the key that was used, then subtract 1 byte because the last value of the tryByteSize threw the exception
unusedSpace = tryByteSize + testQuotaKey.length - 1;
return unusedSpace;
}


function getLocalStorageQuotaInBytes() {
// Returns the total Bytes of Local Storage Space that the browser supports
var unused = getUnusedSpaceOfLocalStorageInBytes();
var used = getUsedSpaceOfLocalStorageInBytes();
var quota = unused + used;
return quota;
}

您可以使用 Blob 函数。获得本地存储数据的当前大小。这可能在旧的浏览器中无法工作,请检查 caniuse 对 new BlobObject.values()的支持。

例如:

return new Blob(Object.values(localStorage)).size;

Value ()将 localStorage 对象转换为数组,Blob 将数组转换为原始数据。

是的,这个问题10年前就问过了。但是对于那些感兴趣的人(比如我,我正在构建一个离线文本编辑器,用本地存储器保存数据)和不擅长编程的人来说,你可以使用这样一些简单的东西:

var warning = 1;
var limit = 2000000; //2 million characters, not really taking in account to bytes but for tested number of characters stored
setInterval(function() {
localStorage["text"] = document.getElementById("editor").innerHTML; //gets text and saves it in local storage under "text"
if(localStorage["text"].length > limit && warning == 1){
alert("Local Storage capacity has been filled");
warning = 2; //prevent a stream of alerts
}
}, 1000);
//setInterval function saves and checks local storage

填充存储空间的最佳方法是查看站点设置(比如,如果将图像存储在本地存储中)。至少在 chrome 中,您可以看到所使用的字节数(即: 1222字节)。但是,使用 js 查看填充本地存储的最佳方法已经在上面提到过,因此使用它们。