Comment trouver la taille de localStorage

117

Je développe actuellement un site qui utilisera localStorage de HTML5. J'ai tout lu sur les limitations de taille pour différents navigateurs. Cependant, je n'ai rien vu sur la façon de connaître la taille actuelle d'une instance localStorage. Cette question semble indiquer que JavaScript n'a pas de méthode intégrée pour afficher la taille d'une variable donnée. Est-ce que localStorage a une propriété de taille de mémoire que je n'ai pas vue? Y a-t-il un moyen facile de faire cela qui me manque?

Mon site est destiné à permettre aux utilisateurs de saisir des informations en mode `` hors ligne '', il est donc très important de pouvoir les avertir lorsque le stockage est presque plein.

dérivation
la source

Réponses:

220

Exécutez cet extrait dans la console JavaScript (version une ligne):

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

Le même code sur plusieurs lignes pour la lecture

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

ou ajoutez ce texte dans le champ 'emplacement' d'un signet pour une utilisation pratique

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

Les extraits PS sont mis à jour en fonction de la demande dans le commentaire. Maintenant, le calcul inclut la longueur de la clé elle-même. Chaque longueur est multipliée par 2 car le caractère dans javascript est stocké en UTF-16 (occupe 2 octets)

PPS devrait fonctionner à la fois dans Chrome et Firefox.

Serge Seletskyy
la source
8
Collez ceci dans la console pour voir le total: var t = 0; pour (var x dans localStorage) {t + = (((localStorage [x] .length * 2))); } console.log (t / 1024 + "Ko");
Henry
5
@Micah Javascript utilise UTF16 en interne, donc comme chaque caractère est stocké sur deux octets, vous devez multiplier le nombre de caractères par deux pour obtenir l'espace réel utilisé. (Vous avez probablement déjà découvert cela, mais j'ai pensé qu'il vaut la peine de le noter ici, car tout le monde a la même question)
Rebecka
2
@Serge, cette réponse est la plus votée, d'où sa publication ici var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");
Mihir
17
Voici une version modifiée qui tient également compte de 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");
Mario Sannum
1
Il y a un bogue dans le bookmarklet. Vous utilisez des variables soulignées dans le code principal et des noms normaux dans le bookmarklet. Un seul souligné le _xbrise. Supprimez simplement le trait de soulignement.
Soul Reaver
46

Partant de ce que @Shourav a dit ci-dessus, j'ai écrit une petite fonction qui devrait saisir avec précision toutes vos localStorageclés (pour le domaine actuel) et calculer la taille combinée afin que vous sachiez exactement combien de mémoire est occupée par votre localStorageobjet:

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

Le mien est revenu: "30.896484375 KB"

tennisgent
la source
1
Merci @tennisgent. Le mien a fonctionné pour IE11, FF> 26 et pour Chrome également.
Akki922234
18

IE a une propriété restanteSpace de l'objet Storage. Les autres navigateurs n'ont pas d'équivilant pour le moment.

Je pense que la quantité d'espace par défaut est de 5 Mo, même si je ne l'ai pas testé personnellement.

Adam
la source
1
Ceci est une propriété IE uniquement
jas-
est la limite de 5 Mo par site ou globalement pour tous les sites?
divyenduz
@divyenduz par site, je pense
Adam
2
Notez que la propriété localStorage.remainingSpace renvoie le nombre restant de caractères UTF-16 autorisés pour l'objet de stockage. PAS la taille restante en octets. Référence
Mihir
14

Voici un exemple simple de la façon de procéder et devrait fonctionner avec tous les navigateurs

alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);
jas-
la source
n'avez-vous pas besoin d'un * 8 quelque part là-dedans?
George Mauer
1
Dépend du jeu de caractères (c'est-à-dire utf8, etc.) dont cela ne tient pas compte
jas-
Cela donne-t-il la taille en octets ou en bits?
JamesTheAwesomeDude
6
Cet exemple suppose à tort que localStorage a la même limite fixe de 5 Mo (5 * 1024 * 1024) dans chaque navigateur.
Victor
C'est selon les spécifications avancées par le w3c.
jas-
13

J'espère que cela aidera quelqu'un.

Parce que Jas- exemple sur jsfiddle ne fonctionne pas pour moi, j'ai trouvé cette solution. (merci à Serge Seletskyy et Shourav pour leurs bits que j'ai utilisés dans le code ci-dessous)

Vous trouverez ci-dessous la fonction qui peut être utilisée pour tester la quantité d'espace disponible pour localStorage et (si des clés sont déjà dans lS) la quantité d'espace restant.

C'est un peu de force brute mais cela fonctionne dans presque tous les navigateurs ... à part Firefox. Eh bien, dans le bureau FF, cela prend du temps (4 à 5 minutes) pour terminer, et sur Android, il se bloque juste.

Sous la fonction se trouve un bref résumé des tests que j'ai effectués dans différents navigateurs sur différentes plates-formes. Prendre plaisir!

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
}

Et comme promis ci-dessus, quelques tests dans différents navigateurs:

GalaxyTab 10.1

  • Maxthon Pad 1,7 ~ 1130 ms 5 Mo
  • Firefox 20.0 (Beta 20.0) a planté les deux
  • Chrome 25.0.1364.169 ~ 22250ms / 5 Mo
  • Natif (identifie comme Safari 4.0 / Webkit534.30) ~ 995 ms / 5 Mo

iPhone 4s iOS 6.1.3

  • Safari ~ 520 ms / 5 Mo
  • Comme HomeApp ~ 525 ms / 5 Mo
  • iCab ~ 710 ms / 5 Mo

MacBook Pro OSX 1.8.3 (mémoire Core 2 Duo 2,66 8 Go)

  • Safari 6.0.3 ~ 105 ms / 5 Mo
  • Chrome 26.0.1410.43 ~ 3400ms / 5 Mo
  • Firefox 20.0 300150ms (!) / 10Mb (après s'être plaint du script trop long)

iPad 3 iOS 6.1.3

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

Windows 7 -64b (mémoire Core 2 Duo 2,93 6 Go)

  • Safari 5.1.7 ~ 80 ms / 5 Mo
  • Chrome 26.0.1410.43 ~ 1220 ms / 5 Mo
  • Firefox 20.0 228500ms (!) / 10Mb (après s'être plaint du script trop long)
  • IE9 ~ 17900ms /9.54Mb (si des consoles.logs sont dans le code ne fonctionne pas jusqu'à ce que DevTools soit ouvert)
  • Opera 12.15 ~ 4212ms /3.55Mb (c'est lorsque 5Mb est sélectionné, mais Opera demande gentiment si nous voulons augmenter la quantité de lS, malheureusement il plante si le test est effectué plusieurs fois de suite)

Win 8 (sous Parallels 8)

  • IE10 ~ 7850 ms / 9,54 Mo
Jakub Gadkowski
la source
Bonnes expériences. Cependant, j'ai trouvé array.forEach()dans votre code, comme je sais qu'il n'existe pas dans IE, l'implémentez-vous vous-même? Comment mesurez-vous sa contribution à la latence globale?
Evi Song
Merci, je pourrais peut-être les refaire car un certain temps s'est écoulé depuis les premiers tests. Quant au forEach(). Non je ne l'ai pas implémenté moi-même, j'ai utilisé le stock Array.prototype.forEach(). Selon Mozilla Developer Network, alias MDN d'IE9, il dispose d'un support natif.
Jakub Gadkowski
Merci. Mes connaissances doivent être rafraîchies. Plus tard, j'utiliserai Array.prototype.forEach()autant que possible si mon projet ne prend pas en charge les premières versions d'IE.
Evi Song
Le code pourrait être rendu beaucoup plus rapide (~ 2500 ms dans Firefox, ~ 700 ms dans Chrome): whileboucle divisée en deux parties, la première comme dans stackoverflow.com/a/3027249/1235394 qui remplit localStorage avec des blocs de données à croissance exponentielle, puis la deuxième partie avec petits morceaux de taille fixe pour remplir complètement le stockage. Page de test: jsfiddle.net/pqpps3tk/1
Victor
IE10 Rocks .. Encore, le navigateur le plus rapide pour télécharger Chrome :)
Ruslan Abuzant
11

Vous pouvez obtenir la taille actuelle des données de stockage local à l'aide de la fonction Blob. Cela peut ne pas fonctionner dans les anciens navigateurs, vérifiez le support pour new Blobet Object.values()sur caniuse.

Exemple:

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

Object.values ​​() transforme l'objet localStorage en tableau. Blob transforme le tableau en données brutes.

P Roitto
la source
3
Je pense que Blobcela ne limite pas l'encodage de chaîne à UTF-16, donc cela pourrait en fait être la méthode la plus fiable. new Blob(['X']).size;= 1 alors que new Blob(['☃']).size(U + 2603 / caractère bonhomme de neige) ==> 3. Les solutions basées sur String.prototype.lengthne prennent pas cela en compte (traitez les "caractères") alors que les quotas / limites de stockage le font probablement (traitent des octets), et je pourrais imaginer cela entraîne des surprises, par exemple, lors du stockage de caractères non anglais / ASCII.
iX3 du
J'ai utilisé la réponse de Jed qui calcule la taille de stockage local avec la longueur des chaînes pour tester la solution Blob dans Chrome & FF. Dans le premier test, j'ai rempli localStorage avec le signe «1». dans le deuxième test, j'ai rempli localStorage avec le signe '' ☃ '' qui a une taille plus grande dans l'objet Blob. Dans les deux cas, j'ai exactement la même longueur maximale de localStorage. La taille des caractères blob n'affecte donc pas la limitation de localStorage. C'est pourquoi Blob ne doit pas être utilisé à cette fin.
Vincente le
6

Vous pouvez calculer votre stockage local en utilisant les méthodes suivantes:

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

Enfin, la taille en octets sera enregistrée dans le navigateur.

Usman Faisal
la source
4

J'utiliserais le code de @tennisgen qui récupère tout et compte le contenu, mais je compte les clés elles-mêmes:

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
la source
3

La façon dont j'ai abordé ce problème est de créer des fonctions pour découvrir l'espace utilisé et l'espace restant dans le stockage local, puis une fonction qui appelle ces fonctions pour déterminer l'espace de stockage maximal.

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
la source
Array.join est un tueur de performances, mieux vaut utiliser String.repeat là où il est disponible (cela signifie partout sauf IE)
pkExec
2

En plus de la réponse de @ serge qui est la plus votée ici, la taille des clés doit être prise en compte. Le code ci-dessous ajoutera la taille des clés stockées danslocalStorage

var t = 0; 
for (var x in localStorage) { 
    t += (x.length + localStorage[x].length) * 2; 
} 
console.log((t / 1024) + " KB");
Mihir
la source
J'ai trouvé que Firefox revient undefined pour l'élément lengthdans certains cas, donc j'ai ajouté une condition à l'addition: t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;.
camilokawerin
@camilokawerin, cela ne devrait pas être le cas à moins qu'une valeur non définie ne soit enregistrée dans le stockage, car String est le seul type pris en charge avec localStorage et String a la propriété Length. Pourriez-vous publier un exemple sur jsfiddle ou quelque chose de similaire?
Mihir
1

Selon les spécifications, chaque caractère d'une chaîne est de 16 bits.

Mais l'inspection avec chrome (Paramètres> Paramètres de contenu> Cookies et données de site) nous montre que le lancement de localStorage prend 3 Ko (taille de surcharge)

Et la taille des données stockées suit cette relation (précise à 1 Ko)
3 + ((localStorage.x.length * 16) / (8 * 1024)) Ko

où localStorage.x est votre chaîne de stockage.

ShouravBR
la source
0

// La mémoire occupe à la fois la clé et la valeur, donc le code mis à jour.

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
la source
0

Oui, cette question a été posée il y a 10 ans. Mais pour ceux qui sont intéressés (comme moi, car je suis en train de créer un éditeur de texte hors ligne qui enregistre les données avec un stockage local) et que la programmation est nulle, vous pouvez utiliser quelque chose de simple comme celui-ci:

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

La meilleure façon d'obtenir la quantité de stockage remplie est d'afficher les paramètres du site (par exemple, si vous avez stocké une image dans le stockage local). Au moins dans Chrome, vous pouvez voir la quantité d'octets utilisés (c'est-à-dire: 1222 octets). Cependant, les meilleures façons de voir le stockage local rempli avec js ont déjà été mentionnées ci-dessus, alors utilisez-les.

Nathan Su
la source
-2
window.localStorage.remainingSpace
Pradeep Singh
la source
8
Comme indiqué ci-dessus, il s'agit d'une propriété réservée à IE.
Rafi Jacoby