web-dev-qa-db-fra.com

Comment trouver la taille de localStorage

Je développe actuellement un site qui utilisera le stockage local 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 manière intégrée d'indiquer 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 at-il un moyen facile de faire cela qui me manque?

Mon site est conçu pour 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. 

84
derivation

Exécutez cet extrait dans la console 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");

ou ajoutez ce texte dans le champ 'location' 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")); 

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

P.P.S. Devrait fonctionner à la fois dans Chrome et Firefox.

155
Serge Seletskyy

En reprenant ce que @Shourav a dit plus haut, j'ai écrit une petite fonction qui devrait saisir avec précision toutes vos clés localStorage (pour le domaine actuel) et calculer la taille combinée afin que vous sachiez exactement combien de mémoire est utilisée par votre objet 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)';
    };

Mine retournée: "30.896484375 KB"

40
tennisgent

IE a une propriété espace restant 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, bien que je ne l’aie pas testée personnellement.

15
Adam

Voici un simple exemple de la façon de le faire et devrait fonctionner avec tous les navigateurs

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

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

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

Ci-dessous se trouve la fonction qui peut être utilisée pour tester combien d’espace est disponible pour localStorage et (si des clés sont déjà dans lS) combien d’espace est disponible. 

C'est un peu la force brute mais cela fonctionne dans presque tous les navigateurs ... à part Firefox . Bien dans le bureau FF cela prend du temps (4-5min) à compléter, et sur Android ça tombe en panne. 

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 ~ 1130ms 5Mb
  • Firefox 20.0 (Beta 20.0) s'est écrasé à la fois
  • Chrome 25.0.1364.169 ~ 22250ms/5Mb
  • Natif (identifie comme Safari 4.0/Webkit534.30) ~ 995ms/5Mb

iPhone 4s iOS 6.1.3

  • Safari ~ 520ms/5Mb
  • En tant que HomeApp ~ 525ms/5Mb 
  • iCab ~ 710ms/5mb

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

  • Safari 6.0.3 ~ 105ms/5Mb
  • Chrome 26.0.1410.43 ~ 3400ms/5Mb
  • Firefox 20.0 300150ms (!)/10Mb (après s'être plaint de l'exécution d'un script trop long)

iPad 3 iOS 6.1.3

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

Windows 7 -64b (mémoire Core 2 Duo 2.93 6Gb)

  • Safari 5.1.7 ~ 80ms/5Mb
  • Chrome 26.0.1410.43 ~ 1220ms/5Mb
  • Firefox 20.0 228500ms (!)/10Mb (après s'être plaint de l'exécution trop longue d'un script)
  • IE9 ~ 17900 ms/9,54 Mo (si des consoles.log sont dans le code, elles ne fonctionneront pas tant que DevTools n'aura pas été ouvert)
  • Opera 12.15 ~ 4212ms /3.55Mb (c'est quand 5Mo est sélectionné, mais Opera demande gentiment si nous voulons augmenter la quantité de lS, malheureusement il se bloque si le test est effectué plusieurs fois de suite)

Win 8 (Under Parallels 8)

  • IE10 ~ 7850ms /9.54Mb
10
Jakub Gadkowski

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.

5
Usman Faisal

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

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

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

Pour résoudre ce problème, j'ai créé des fonctions permettant de connaître l'espace utilisé et l'espace restant dans le stockage local, puis une fonction appelant 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;
}
1
Jed

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

Mais inspecter avec du chrome (Paramètres> Paramètres de contenu> Cookies et données de site) nous montre que lancer LocalStorage prend 3 Ko (taille de l’en-tête)

Et la taille des données stockées suit cette relation (avec une précision de 1 Ko)
3 + ((localStorage.x.length * 16)/(8 * 1024)) kB

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

1

Vous pouvez obtenir la taille actuelle des données de stockage locales à l’aide de la fonction Blob. Cela peut ne pas fonctionner dans les anciens navigateurs.

Exemple:

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

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

1
P Roitto

// La mémoire occupe à la fois la clé et la valeur du 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]);
0
Dipak Prajapati