So ermitteln Sie die Größe von localStorage

117

Ich entwickle derzeit eine Site, die den localStorage von HTML5 verwendet. Ich habe alles über die Größenbeschränkungen für verschiedene Browser gelesen. Ich habe jedoch noch nichts darüber gesehen, wie die aktuelle Größe einer localStorage-Instanz ermittelt werden kann. Diese Frage scheint darauf hinzudeuten, dass in JavaScript die Größe für eine bestimmte Variable nicht integriert ist. Hat localStorage eine Speichergrößeneigenschaft, die ich nicht gesehen habe? Gibt es eine einfache Möglichkeit, dies zu tun, die mir fehlt?

Meine Website soll es Benutzern ermöglichen, Informationen in einem "Offline" -Modus einzugeben. Daher ist es sehr wichtig, sie warnen zu können, wenn der Speicher fast voll ist.

Ableitung
quelle

Antworten:

219

Führen Sie dieses Snippet in der JavaScript-Konsole aus (einzeilige Version):

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");

Der gleiche Code in mehreren Zeilen zum Lesen

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");

oder fügen Sie diesen Text zur bequemen Verwendung in das Feld 'Speicherort' eines Lesezeichens ein

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")); 

PS-Snippets werden gemäß der Anfrage im Kommentar aktualisiert. Jetzt beinhaltet die Berechnung die Länge des Schlüssels selbst. Jede Länge wird mit 2 multipliziert, da das Zeichen in Javascript als UTF-16 gespeichert wird (2 Bytes belegt).

PPS sollte sowohl in Chrome als auch in Firefox funktionieren.

Serge Seletskyy
quelle
8
Fügen Sie dies in die Konsole ein, um die Summe anzuzeigen: var t = 0; für (var x in localStorage) {t + = (((localStorage [x] .length * 2))); } console.log (t / 1024 + "KB");
Henry
5
@Micah Javascript verwendet UTF16 intern. Da jedes Zeichen als zwei Bytes gespeichert ist, müssen Sie die Anzahl der Zeichen mit zwei multiplizieren, um den tatsächlich verwendeten Speicherplatz zu erhalten. (Sie haben dies wahrscheinlich bereits entdeckt, aber ich dachte, es ist erwähnenswert, nur für alle anderen, die die gleiche Frage haben)
Michael
2
@ Serge, diese Antwort ist am meisten gewählt, daher hier posten var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");
Mihir
17
Hier ist eine modifizierte Version, die auch NaN var _lsTotal = 0, _xLen, _x; for (_x in localStorage) { _xLen = (((localStorage[_x].length || 0) + (_x.length || 0)) * 2); _lsTotal += _xLen; console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB") }; console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");
berücksichtigt
1
Es gibt einen Fehler im Lesezeichen. Sie verwenden unterstrichene Variablen im Hauptcode und normale Namen im Lesezeichen. Single unterstrichen _xbricht es. Entfernen Sie einfach den Unterstrich.
Soul Reaver
46

Ausgehend von dem, was @Shourav oben gesagt hat, habe ich eine kleine Funktion geschrieben, die alle localStorageSchlüssel (für die aktuelle Domain) genau erfassen und die kombinierte Größe berechnen soll, damit Sie genau wissen, wie viel Speicher von Ihrem localStorageObjekt belegt wird:

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)';
    };

Meins kehrte zurück: "30.896484375 KB"

Tennisagent
quelle
1
Danke @tennisgent. Meins arbeitete für IE11, FF> 26 und auch für Chrome.
Akki922234
18

IE hat eine verbleibende Space- Eigenschaft des Speicherobjekts. Die anderen Browser haben derzeit keine Äquivalenz.

Ich glaube, dass der Standardspeicherplatz 5 MB beträgt, obwohl ich ihn nicht persönlich getestet habe.

Adam
quelle
1
Dies ist eine IE only-Eigenschaft
jas-
ist das 5-MB-Limit pro Site oder insgesamt für alle Sites?
Divyenduz
@ Divyenduz pro Website, denke ich
Adam
2
Beachten Sie, dass die Eigenschaft localStorage.remainingSpace die verbleibende Anzahl von UTF-16-Zeichen zurückgibt, die für das Speicherobjekt zulässig sind. NICHT die verbleibende Größe in Bytes. Referenz
Mihir
14

Hier ist ein einfaches Beispiel dafür und sollte mit jedem Browser funktionieren

alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);
jas-
quelle
brauchst du da nicht irgendwo eine * 8?
George Mauer
1
Hängt vom Zeichensatz ab (dh utf8 usw.), der nicht berücksichtigt wird
jas-
Gibt dies die Größe in Bytes oder in Bits an?
JamesTheAwesomeDude
6
In diesem Beispiel wird fälschlicherweise davon ausgegangen, dass localStorage in jedem Browser dieselbe feste Grenze in 5 MB (5 * 1024 * 1024) hat.
Victor
Das entspricht der Spezifikation des w3c.
Jas-
13

Hoffe das hilft jemandem.

Da Jas-Beispiel auf jsfiddle für mich nicht funktioniert, habe ich diese Lösung gefunden. (Danke an Serge Seletskyy und Shourav für ihre Bits, die ich im folgenden Code verwendet habe)

Im Folgenden finden Sie die Funktion, mit der Sie testen können, wie viel Speicherplatz für localStorage verfügbar ist und (falls noch Schlüssel in lS vorhanden sind) wie viel Speicherplatz noch vorhanden ist.

Es ist ein wenig brutale Gewalt, aber es funktioniert in fast jedem Browser ... außer in Firefox. Nun, in Desktop-FF dauert es ewig (4-5 Minuten), und unter Android stürzt es einfach ab.

Unter der Funktion befindet sich eine kurze Zusammenfassung der Tests, die ich in verschiedenen Browsern auf verschiedenen Plattformen durchgeführt habe. Genießen!

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
}

Und wie oben versprochen einige Tests in verschiedenen Browsern:

GalaxyTab 10.1

  • Maxthon Pad 1,7 ~ 1130 ms 5 MB
  • Firefox 20.0 (Beta 20.0) stürzte beide ab
  • Chrome 25.0.1364.169 ~ 22250 ms / 5 MB
  • Native (identifiziert als Safari 4.0 / Webkit534.30) ~ 995 ms / 5 MB

iPhone 4s iOS 6.1.3

  • Safari ~ 520 ms / 5 MB
  • Als HomeApp ~ 525ms / 5Mb
  • iCab ~ 710 ms / 5 MB

MacBook Pro OSX 1.8.3 (Core 2 Duo 2.66 8 GB Speicher)

  • Safari 6.0.3 ~ 105 ms / 5 MB
  • Chrome 26.0.1410.43 ~ 3400 ms / 5 MB
  • Firefox 20.0 300150ms (!) / 10Mb (nachdem Sie sich über ein zu langes Skript beschwert haben)

iPad 3 iOS 6.1.3

  • Safari ~ 430 ms / 5 MB
  • iCab ~ 595 ms / 5 MB

Windows 7 -64b (Core 2 Duo 2.93 6Gb Speicher)

  • Safari 5.1.7 ~ 80 ms / 5 MB
  • Chrome 26.0.1410.43 ~ 1220 ms / 5 MB
  • Firefox 20.0 228500ms (!) / 10Mb (nachdem Sie sich über ein zu langes Skript beschwert haben)
  • IE9 ~ 17900ms /9.54Mb (wenn sich console.logs im Code befinden, funktioniert dies erst, wenn DevTools geöffnet werden)
  • Opera 12.15 ~ 4212ms /3.55Mb (dies ist, wenn 5Mb ausgewählt ist, aber Opera fragt freundlich, ob wir die Menge an lS erhöhen möchten, leider stürzt es ab, wenn der Test einige Male hintereinander durchgeführt wird)

Gewinnen Sie 8 (unter Parallelen 8)

  • IE10 ~ 7850 ms / 9,54 MB
Jakub Gadkowski
quelle
Tolle Experimente. Wie auch immer ich array.forEach()in Ihrem Code gefunden habe, da ich weiß, dass er im IE nicht vorhanden ist, implementieren Sie ihn selbst? Wie messen Sie den Beitrag zur Gesamtlatenz?
Evi Song
Vielen Dank, ich könnte sie wiederholen, da einige Zeit von den ersten Tests vergangen ist. Wie für die forEach(). Nein, ich habe es nicht selbst implementiert, ich habe die Aktie verwendet Array.prototype.forEach(). Laut Mozilla Developer Network, auch bekannt als MDN von IE9, wird es nativ unterstützt.
Jakub Gadkowski
Vielen Dank. Mein Wissen muss aufgefrischt werden. Später werde ich Array.prototype.forEach()so viel wie möglich verwenden, wenn mein Projekt frühe IE-Versionen nicht unterstützt.
Evi Song
Code könnte erheblich schneller gemacht werden (~ 2500 ms in Firefox, ~ 700 ms in Chrome): Aufteilen der whileSchleife in zwei Teile, der erste wie in stackoverflow.com/a/3027249/1235394 , der localStorage mit exponentiell wachsenden Datenblöcken füllt, dann der zweite Teil mit kleine Stücke mit fester Größe, um den Speicher vollständig zu füllen. Testseite
Victor
IE10 Rocks .. Immer noch der schnellste Browser zum Herunterladen von Chrome :)
Ruslan Abuzant
11

Mit der Blob-Funktion können Sie die aktuelle Größe der lokalen Speicherdaten abrufen. Dies funktioniert möglicherweise nicht in alten Browsern. Überprüfen Sie die Unterstützung für new Blobund Object.values()bei caniuse.

Beispiel:

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

Object.values ​​() wandelt das localStorage-Objekt in ein Array um. Blob wandelt das Array in Rohdaten um.

P Roitto
quelle
3
Ich denke, Blobbeschränkt die Zeichenfolgencodierung nicht auf UTF-16, daher ist dies möglicherweise die zuverlässigste Methode. new Blob(['X']).size;= 1 wohingegen new Blob(['☃']).size(U + 2603 / Schneemannzeichen) ==> 3. Lösungen, die auf basieren String.prototype.length, berücksichtigen dies nicht (befassen sich mit "Zeichen"), wohingegen Speicherquoten / -grenzen wahrscheinlich (mit Bytes umgehen), und ich könnte mir vorstellen Dies führt zu Überraschungen, beispielsweise beim Speichern von nicht englischen / ASCII-Zeichen.
iX3
Ich habe Jeds Antwort verwendet, die die localStorage-Größe mit der Länge der Zeichenfolgen berechnet, um die Blob-Lösung in Chrome und FF zu testen. Im ersten Test habe ich localStorage mit dem Zeichen '1' gefüllt. Im zweiten Test habe ich localStorage mit dem Zeichen '' ☃ '' gefüllt, das im Blob-Objekt größer ist. In beiden Fällen habe ich genau die gleiche maximale localStorage-Länge erhalten. Die Blob-Größe von Zeichen hat also keinen Einfluss auf die localStorage-Einschränkung. Deshalb sollte Blob nicht für diesen Zweck verwendet werden.
Vincente
6

Sie können Ihren lokalen Speicher mit folgenden Methoden berechnen:

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());

Schließlich wird die Größe in Bytes im Browser protokolliert.

Usman Faisal
quelle
4

Ich würde den Code von @tennisgen verwenden, der alle abruft und den Inhalt zählt, aber ich zähle die Schlüssel selbst:

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)';
    };
Arnaud Valensi
quelle
3

Bei diesem Problem habe ich Funktionen erstellt, um den verwendeten Speicherplatz und den verbleibenden Speicherplatz im lokalen Speicher zu ermitteln, und anschließend eine Funktion, die diese Funktionen aufruft, um den maximalen Speicherplatz zu ermitteln.

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'));
            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;
}
Jed
quelle
Array.join ist ein Leistungskiller. Verwenden Sie besser String.repeat, sofern verfügbar (dh überall außer im
Internet Explorer
2

Zusätzlich zu der Antwort von @ serge, über die hier am meisten abgestimmt wird, muss die Größe der Schlüssel berücksichtigt werden. Der folgende Code fügt die Größe der in gespeicherten Schlüssel hinzulocalStorage

var t = 0; 
for (var x in localStorage) { 
    t += (x.length + localStorage[x].length) * 2; 
} 
console.log((t / 1024) + " KB");
Mihir
quelle
Ich habe festgestellt, dass Firefox in einigen Fällen undefinedfür das Element zurückgibt length, daher habe ich dem Zusatz eine Bedingung hinzugefügt : t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;.
Camilokawerin
@camilokawerin sollte dies nicht tun, es sei denn, ein undefinierter Wert wird im Speicher gespeichert, da String der einzige Typ ist, der von localStorage unterstützt wird, und String die Eigenschaft Length hat. Könntest du ein Beispiel auf jsfiddle oder ähnlichem posten?
Mihir
1

Wie die Spezifikation sagt, ist jedes Zeichen einer Zeichenfolge 16 Bit.

Die Überprüfung mit Chrome (Einstellungen> Inhaltseinstellungen> Cookies und Site-Daten) zeigt jedoch, dass das Initiieren von localStorage 3 KB (Overhead-Größe) erfordert.

Die Größe der gespeicherten Daten folgt dieser Beziehung (auf 1 kB genau)
3 + ((localStorage.x.length * 16) / (8 * 1024)) kB

Dabei ist localStorage.x Ihre Speicherzeichenfolge.

ShouravBR
quelle
0

// Speicher belegt sowohl Schlüssel als auch Wert, also aktualisierter Code.

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]);
Dipak Prajapati
quelle
0

Ja, diese Frage wurde wie vor 10 Jahren gestellt. Aber für Interessierte (wie mich selbst, da ich einen Offline-Texteditor baue, der Daten mit lokalem Speicher speichert) und sich für die Programmierung interessieren, könnten Sie etwas Einfaches wie das verwenden:

var warning = 1;
var limit = 2000000; //2 million characters, not really taking in account to bytes but for tested ammounts 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

Der beste Weg, um die Speichermenge zu füllen, besteht darin, die Site-Einstellungen anzuzeigen (z. B. wenn Sie ein Bild im lokalen Speicher gespeichert haben). Zumindest in Chrome können Sie die Anzahl der verwendeten Bytes sehen (dh: 1222 Bytes). Die besten Möglichkeiten, gefüllten lokalen Speicher mit js anzuzeigen, wurden bereits oben erwähnt. Verwenden Sie sie daher.

Nathan Su
quelle
-2
window.localStorage.remainingSpace
Pradeep Singh
quelle
8
Wie oben erwähnt, ist dies eine Nur-IE-Eigenschaft.
Rafi Jacoby