Как узнать размер localStorage


118

В настоящее время я разрабатываю сайт, который будет использовать localStorage HTML5. Я читал все об ограничениях по размеру для разных браузеров. Однако я ничего не видел о том, как узнать текущий размер экземпляра localStorage. Этот вопрос, кажется, указывает на то, что JavaScript не имеет встроенного способа отображения размера данной переменной. Есть ли у localStorage свойство размера памяти, которого я не видел? Есть ли простой способ сделать это, что мне не хватает?

Мой сайт предназначен для того, чтобы пользователи могли вводить информацию в «автономном» режиме, поэтому очень важно иметь возможность предупреждать их, когда хранилище почти заполнено.


Ответы:


222

Выполните этот фрагмент в консоли 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")); 

PS Фрагменты обновляются по запросу в комментарии. Теперь в расчет входит длина самого ключа. Каждая длина умножается на 2, потому что символ в javascript хранится как UTF-16 (занимает 2 байта)

PPS Должен работать как в Chrome, так и в Firefox.


8
Вставьте это в консоль, чтобы увидеть результат: var t = 0; for (var x в localStorage) {t + = (((localStorage [x] .length * 2))); } console.log (t / 1024 + «КБ»);
— Генри

5
@Micah Javascript внутренне использует UTF16, поэтому, поскольку каждый символ хранится в виде двух байтов, вам нужно умножить количество символов на два, чтобы получить фактическое используемое пространство. (Вы, наверное, уже обнаружили это, но я подумал, что стоит отметить здесь, потому что у кого-то еще есть такой же вопрос)
— Ребека

2
@Serge, за этот ответ проголосовало больше всего, поэтому отправляю здесь var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");
— Михир

17
Вот модифицированная версия, которая также учитывает 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");
— Марио Саннум

1
В букмарклете есть ошибка. Вы используете подчеркнутые переменные в основном коде и обычные имена в букмарклете. Одиночное подчеркивание _xломает его. Просто удалите подчеркивание.
— Soul Reaver

46

Исходя из того, что сказал @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"


1
Спасибо @tennisgent. Моя работала для IE11, FF> 26, а также для Chrome.
— Akki922234

18

IE имеет remainingSpace свойство объекта хранения. Остальные браузеры в настоящее время не имеют аналогов.

Я считаю, что объем дискового пространства по умолчанию составляет 5 МБ, хотя лично я его не тестировал.


1
Это свойство только IE
— jas-

ограничение в 5 МБ на сайт или в целом для всех сайтов?
— divyenduz

@divyenduz на сайт, я думаю
— Адам

2
Обратите внимание, что свойство localStorage.remainingSpace возвращает оставшееся количество символов UTF-16, разрешенных для объекта хранения. НЕ оставшийся размер в байтах. Ссылка
— Mihir

14

Вот простой пример того, как это сделать, и он должен работать с каждым браузером.

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

тебе не нужен * 8 где-то там?
— Джордж Мауэр

1
Зависит от набора символов (например, utf8 и т. Д.),
— Который

Это дает размер в байтах или в битах?
— JamesTheAwesomeDude

6
В этом примере неверно предполагается, что localStorage имеет одинаковый фиксированный лимит в 5 МБ (5 * 1024 * 1024) в каждом браузере.
— Виктор

Это согласно спецификации, выдвинутой w3c.
— jas-

13

Надеюсь, это кому-то поможет.

Поскольку пример Jas на jsfiddle у меня не работает, я придумал это решение. (спасибо Serge Seletskyy и 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
}

И, как было обещано выше, несколько тестов в разных браузерах:

GalaxyTab 10.1

  • Maxthon Pad 1.7 ~ 1130 мс 5 МБ
  • Firefox 20.0 (Beta 20.0) вылетел как
  • Chrome 25.0.1364.169 ~ 22250 мс / 5 МБ
  • Собственный (идентифицируется как Safari 4.0 / Webkit534.30) ~ 995 мс / 5 МБ

iPhone 4s iOS 6.1.3

  • Safari ~ 520 мс / 5 Мб
  • Как HomeApp ~ 525 мс / 5 МБ
  • iCab ~ 710 мс / 5 МБ

MacBook Pro OSX 1.8.3 (Core 2 Duo 2,66 8 ГБ памяти)

  • Safari 6.0.3 ~ 105 мс / 5 Мб
  • Chrome 26.0.1410.43 ~ 3400 мс / 5 МБ
  • Firefox 20.0 300150 мс (!) / 10 МБ (после жалобы на долгую работу скрипта)

iPad 3 iOS 6.1.3

  • Safari ~ 430 мс / 5 Мб
  • iCab ~ 595 мс / 5 МБ

Windows 7 -64b (Core 2 Duo 2,93 6 ГБ памяти)

  • Safari 5.1.7 ~ 80 мс / 5 Мб
  • Chrome 26.0.1410.43 ~ 1220 мс / 5 МБ
  • Firefox 20.0 228500 мс (!) / 10 МБ (после жалобы на слишком долгую работу скрипта)
  • IE9 ~ 17900 мс / 9,54 Мб (если в коде есть console.logs, не работает, пока не откроются DevTools)
  • Opera 12.15 ~ 4212 мс / 3,55 МБ (это когда выбрано 5 МБ, но Opera красиво спрашивает, хотим ли мы увеличить количество lS, к сожалению, он вылетает, если тест проводится несколько раз подряд)

Победа 8 (в параллелях 8)

  • IE10 ~ 7850 мс / 9,54 МБ

Отличные эксперименты. Однако я нашел array.forEach()в вашем коде, поскольку я знаю, что его нет в IE, вы реализуете самостоятельно? Как вы измеряете его вклад в общую задержку?
— Evi Song

Спасибо, я мог бы переделать их, так как прошло некоторое время с первоначальных тестов. Что касается forEach(). Нет, сам не реализовал, использовал сток Array.prototype.forEach(). Согласно Mozilla Developer Network, также известной как MDN из IE9, он имеет встроенную поддержку.
— Якуб Гадковски

Спасибо. Мои знания нуждаются в обновлении. Позже я буду использовать Array.prototype.forEach()как можно больше, если мой проект не будет поддерживать ранние версии IE.
— Evi Song

Код можно сделать значительно быстрее (~ 2500 мс в Firefox, ~ 700 мс в Chrome): разделить whileцикл на две части, первую, как в stackoverflow.com/a/3027249/1235394, которая заполняет localStorage экспоненциально растущими порциями данных, а затем вторая часть с небольшие фрагменты фиксированного размера для полного заполнения хранилища. Тестовая страница: jsfiddle.net/pqpps3tk/1
— Виктор

IE10 Rocks .. Тем не менее, самый быстрый браузер для загрузки Chrome :)
— Руслан Абузант

11

Вы можете получить текущий размер данных локального хранилища с помощью функции Blob. Это может не работать в старых браузерах, проверьте поддержку new Blobи Object.values()на caniuse.

Пример:

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

Object.values ​​() превращает объект localStorage в массив. Blob превращает массив в необработанные данные.


3
Я думаю, Blobчто не ограничивает строковую кодировку UTF-16, поэтому это может быть самый надежный метод. new Blob(['X']).size;= 1, тогда как new Blob(['☃']).size(U + 2603 / персонаж снеговика) ==> 3. Решения, основанные на этом String.prototype.length, не принимают это во внимание (имеют дело с «персонажами»), тогда как квоты / ограничения хранилища, вероятно, учитывают (имеют дело с байтами), и я мог представить это приводило к неожиданностям, например, при хранении неанглийских символов / символов ASCII.
— iX3

Я использовал ответ Джеда, который вычисляет размер localStorage с длиной строк для тестирования решения Blob в Chrome и FF. В первом тесте я заполнил localStorage знаком «1». во втором тесте я заполнил localStorage знаком «☃», который имеет больший размер в объекте Blob. В обоих случаях я получил одинаковую максимальную длину localStorage. Таким образом, размер символа Blob не влияет на ограничение localStorage. Вот почему Blob не следует использовать для этой цели.
— Винсенте,

6

Вы можете рассчитать местное хранилище следующими способами:

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

Наконец, размер в байтах будет зарегистрирован в браузере.


4

Я бы использовал код @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)';
    };

3

Я решил эту проблему так, чтобы создать функции для определения используемого и оставшегося пространства в локальном хранилище, а затем функцию, которая вызывает эти функции для определения максимального объема хранилища.

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

Array.join - убийца производительности, лучше используйте String.repeat там, где это возможно (то есть везде, кроме IE)
— pkExec 01

2

В дополнение к ответу @ serge, который получил здесь наибольшее количество голосов, необходимо учитывать размер ключей. Код ниже добавит размер ключей, хранящихся вlocalStorage

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

Я обнаружил , что Firefox возвращает undefinedдля элемента lengthв некоторых случаях, поэтому я добавил условное добавления: t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;.
— camilokawerin

@camilokawerin, этого не должно быть, если в хранилище не сохранено неопределенное значение, потому что String - единственный тип, который поддерживается с помощью localStorage, а String действительно имеет свойство Length. Не могли бы вы опубликовать пример на jsfiddle или что-то подобное?
— Mihir

1

Согласно спецификации, каждый символ строки составляет 16 бит.

Но проверка с помощью Chrome (Настройки> Настройки контента> Файлы cookie и данные сайта) показывает нам, что запуск localStorage занимает 3 КБ (размер накладных расходов).

И размер хранимых данных следует этому соотношению (с точностью до 1 КБ)
3 + ((localStorage.x.length * 16) / (8 * 1024)) КБ

где localStorage.x - строка вашего хранилища.


0

// Память занята как ключом, так и значением, поэтому обновленный код.

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

Да, этот вопрос задавали лет 10 назад. Но для тех, кто интересуется (например, я, поскольку я создаю автономный текстовый редактор, который сохраняет данные в локальном хранилище) и не умеет программировать, вы можете использовать что-то простое, например:

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

Лучший способ получить заполненный объем хранилища - это просмотреть настройки сайта (например, если вы сохранили изображение в локальном хранилище). По крайней мере, в Chrome вы можете увидеть количество использованных байтов (например, 1222 байта). Однако лучшие способы увидеть заполненное локальное хранилище с помощью js уже упоминались выше, поэтому используйте их.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.