Bagaimana menemukan ukuran localStorage


117

Saat ini saya mengembangkan situs yang akan menggunakan localStorage HTML5. Saya telah membaca semua tentang batasan ukuran untuk browser yang berbeda. Namun, saya belum melihat apa pun tentang cara mengetahui ukuran instance localStorage saat ini. Pertanyaan ini sepertinya menunjukkan bahwa JavaScript tidak memiliki cara bawaan untuk menampilkan ukuran variabel tertentu. Apakah localStorage memiliki properti ukuran memori yang belum pernah saya lihat? Apakah ada cara mudah untuk melakukan ini yang saya lewatkan?

Situs saya dimaksudkan untuk memungkinkan pengguna memasukkan informasi dalam mode 'offline', jadi sangat penting untuk dapat memberi mereka peringatan ketika penyimpanan hampir penuh.


Jawaban:


219

Jalankan cuplikan ini di konsol JavaScript (versi satu baris):

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

Kode yang sama dalam beberapa baris untuk dibaca

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

atau tambahkan teks ini di bidang 'lokasi' penanda untuk penggunaan yang nyaman

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

Cuplikan PS diperbarui sesuai permintaan di komentar. Sekarang perhitungannya mencakup panjang kunci itu sendiri. Setiap panjang dikalikan dengan 2 karena karakter di javascript disimpan sebagai UTF-16 (menempati 2 byte)

PPS Seharusnya berfungsi baik di Chrome dan Firefox.


8
Tempel ini di konsol untuk melihat total: var t = 0; untuk (var x di localStorage) {t + = (((localStorage [x] .length * 2))); } console.log (t / 1024 + "KB");
Henry

5
@Micah Javascript menggunakan UTF16 secara internal, jadi karena setiap karakter disimpan sebagai dua byte Anda perlu mengalikan jumlah karakter dengan dua untuk mendapatkan ruang yang sebenarnya digunakan. (Anda mungkin telah menemukan ini, tapi saya pikir perlu dicatat di sini hanya karena orang lain memiliki pertanyaan yang sama)
Rebecka

2
@Serge, jawaban ini paling banyak dipilih maka posting di sini var t = 0; for(var x in localStorage) { t += (x.length + localStorage[x].length) * 2; } console.log(t/1024+ " KB");
Mihir

17
Berikut adalah versi modifikasi yang memperhitungkan NaN juga: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
Ada bug di bookmarklet. Anda menggunakan variabel yang digarisbawahi di kode utama dan nama normal di bookmarklet. Satu garis bawah _xmematahkannya. Hapus saja garis bawah.
Soul Reaver

46

Berangkat dari apa yang dikatakan @Shourav di atas, saya menulis sebuah fungsi kecil yang harus secara akurat mengambil semua localStoragekunci Anda (untuk domain saat ini) dan menghitung ukuran gabungan sehingga Anda tahu persis berapa banyak memori yang diambil oleh localStorageobjek Anda :

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

Milik saya dikembalikan: "30.896484375 KB"


1
Terima kasih @tennisgent. Punyaku bekerja untuk IE11, FF> 26 dan untuk Chrome juga.
Akki922234

18

IE memiliki properti sisa ruang dari objek Penyimpanan. Browser lain tidak memiliki persamaan saat ini.

Saya percaya bahwa jumlah ruang default adalah 5MB, meskipun saya belum mengujinya secara pribadi.


1
Ini adalah satu-satunya properti di IE
jas-

apakah batas 5 mb per situs atau keseluruhan untuk semua situs?
divyenduz

@divyenduz per situs, saya pikir
Adam

2
Perhatikan bahwa properti localStorage.remainingSpace mengembalikan sisa jumlah karakter UTF-16 yang diizinkan untuk objek penyimpanan. BUKAN ukuran yang tersisa dalam byte. Referensi
Mihir

14

Berikut adalah contoh sederhana tentang cara melakukan ini dan harus bekerja dengan setiap browser

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

tidakkah kamu membutuhkan * 8 di suatu tempat di sana?
George Mauer

1
Tergantung pada set karakter (yaitu utf8, dll) yang tidak diperhitungkan
jas-

Apakah ini memberikan ukuran dalam byte, atau dalam bit?
JamesTheAwesomeDude

6
Contoh ini salah mengasumsikan bahwa localStorage memiliki batas tetap yang sama di 5MB (5 * 1024 * 1024) di setiap browser.
Victor

Itu sesuai dengan spesifikasi yang diajukan oleh w3c.
jas-

13

Semoga ini membantu seseorang.

Karena Jas- example di jsfiddle tidak berfungsi untuk saya, saya datang dengan solusi ini. (terima kasih kepada Serge Seletskyy dan Shourav untuk bit mereka yang saya gunakan dalam kode di bawah)

Di bawah ini adalah fungsi yang dapat digunakan untuk menguji seberapa banyak ruang yang tersedia untuk localStorage dan (jika ada kunci yang sudah ada di lS) berapa banyak ruang yang tersisa.

Ini adalah sedikit kekerasan tetapi bekerja di hampir semua browser ... selain Firefox. Nah di FF desktop dibutuhkan waktu lama (4-5 menit) untuk menyelesaikannya, dan di Android itu hanya macet.

Di bawah fungsinya adalah ringkasan singkat dari tes yang telah saya lakukan di browser yang berbeda pada platform yang berbeda. Nikmati!

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
}

Dan seperti yang dijanjikan di atas beberapa tes di browser yang berbeda:

GalaxyTab 10.1.0

  • Maxthon Pad 1.7 ~ 1130ms 5Mb
  • Firefox 20.0 (Beta 20.0) mengalami crash keduanya
  • Chrome 25.0.1364.169 ~ 22250ms / 5Mb
  • Asli (diidentifikasi sebagai Safari 4.0 / Webkit534.30) ~ 995ms / 5Mb

iPhone 4s iOS 6.1.3

  • Safari ~ 520ms / 5Mb
  • Sebagai HomeApp ~ 525ms / 5Mb
  • iCab ~ 710ms / 5mb

MacBook Pro OSX 1.8.3 (memori Core 2 Duo 2.66 8 Gb)

  • Safari 6.0.3 ~ 105ms / 5Mb
  • Chrome 26.0.1410.43 ~ 3400ms / 5Mb
  • Firefox 20.0 300150ms (!) / 10Mb (setelah mengeluh tentang skrip yang berjalan terlalu lama)

iPad 3 iOS 6.1.3

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

Windows 7-64b (memori Core 2 Duo 2,93 6Gb)

  • Safari 5.1.7 ~ 80ms / 5Mb
  • Chrome 26.0.1410.43 ~ 1220ms / 5Mb
  • Firefox 20.0 228500ms (!) / 10Mb (setelah mengeluh tentang skrip yang berjalan terlalu lama)
  • IE9 ~ 17900ms /9.54Mb (jika ada console.logs di dalam kode tidak berfungsi sampai DevTools dibuka)
  • Opera 12.15 ~ 4212ms /3.55Mb (ini adalah saat 5Mb dipilih, tetapi Opera bertanya dengan baik apakah kami ingin meningkatkan jumlah lS, sayangnya itu macet jika pengujian dilakukan beberapa kali berturut-turut)

Menang 8 (Di Bawah Parallels 8)

  • IE10 ~ 7850ms /9.54Mb

Eksperimen hebat. Namun saya menemukan array.forEach()di kode Anda, karena saya tahu itu tidak ada di IE, apakah Anda menerapkannya sendiri? Bagaimana Anda mengukur kontribusinya terhadap latensi keseluruhan?
Evi Song

Terima kasih, saya mungkin akan mengulanginya karena beberapa waktu berlalu dari tes awal. Adapun forEach(). Tidak, saya belum menerapkannya sendiri, saya menggunakan stok Array.prototype.forEach(). Menurut Jaringan Pengembang Mozilla alias MDN dari IE9 itu memiliki dukungan asli.
Jakub Gadkowski

Terima kasih. Pengetahuan saya perlu disegarkan. Nanti saya akan menggunakan Array.prototype.forEach()sebanyak mungkin jika proyek saya tidak mendukung versi IE awal.
Evi Song

Kode dapat dibuat secara signifikan lebih cepat (~ 2500ms di Firefox, ~ 700ms di Chrome): split whileloop menjadi dua bagian, yang pertama seperti di stackoverflow.com/a/3027249/1235394 yang mengisi localStorage dengan potongan data yang tumbuh secara eksponensial, lalu bagian kedua dengan potongan kecil berukuran tetap untuk mengisi penyimpanan sepenuhnya. Halaman pengujian: jsfiddle.net/pqpps3tk/1
Victor

IE10 Rocks .. Tetap saja, browser tercepat untuk mengunduh Chrome :)
Ruslan Abuzant

11

Anda bisa mendapatkan ukuran saat ini dari data penyimpanan lokal menggunakan fungsi Blob. Ini mungkin tidak berfungsi di browser lama, periksa dukungan untuk new Blobdan Object.values()di caniuse.

Contoh:

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

Object.values ​​() mengubah objek localStorage menjadi sebuah array. Blob mengubah array menjadi data mentah.


3
Saya pikir Blobtidak membatasi pengkodean string ke UTF-16, jadi ini mungkin metode yang paling dapat diandalkan. new Blob(['X']).size;= 1 sedangkan new Blob(['☃']).size(U + 2603 / karakter manusia salju) ==> 3. Solusi berdasarkan String.prototype.lengthjangan memperhitungkan ini (berurusan dengan "karakter") sedangkan kuota / batas penyimpanan kemungkinan besar (menangani byte), dan saya bisa membayangkan hal ini menimbulkan kejutan, misalnya, saat menyimpan karakter non-Inggris / ASCII.
iX3

Saya menggunakan jawaban Jed yang menghitung ukuran penyimpanan lokal dengan panjang string untuk menguji solusi Blob di Chrome & FF. Pada tes pertama, saya mengisi localStorage dengan tanda '1'. Pada pengujian kedua, saya mengisi localStorage dengan tanda '' ☃ '' yang ukurannya lebih besar pada objek Blob. Dalam kedua kasus, saya mendapatkan panjang Penyimpanan lokal maksimum yang persis sama. Jadi ukuran karakter Blob tidak mempengaruhi batasan Penyimpanan lokal. Itulah mengapa Blob tidak boleh digunakan untuk tujuan ini.
Vincente

6

Anda dapat menghitung penyimpanan lokal Anda dengan metode berikut:

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

Akhirnya ukuran dalam byte akan dicatat di browser.


4

Saya akan menggunakan kode @tennisgen yang mendapatkan semua dan menghitung konten, tetapi saya menghitung kuncinya sendiri:

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

Cara saya mengatasi masalah ini adalah membuat fungsi untuk mengetahui ruang yang digunakan dan ruang yang tersisa di Penyimpanan Lokal dan kemudian fungsi yang memanggil fungsi-fungsi tersebut untuk menentukan ruang penyimpanan maksimal.

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 adalah pembunuh kinerja, lebih baik gunakan String.repeat jika tersedia (artinya di mana-mana kecuali IE)
pkExec

2

Selain jawaban @ serge yang paling banyak dipilih di sini, ukuran kunci perlu dipertimbangkan. Kode di bawah ini akan menambah ukuran kunci yang disimpanlocalStorage

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

Saya telah menemukan bahwa Firefox kembali undefineduntuk item lengthdalam beberapa kasus, jadi saya telah menambahkan bersyarat untuk penambahan: t += (x.length + (this.storage[x].length ? this.storage[x].length : 0)) * 2;.
camilokawerin

@camilokawerin, seharusnya tidak kecuali nilai yang tidak ditentukan disimpan di penyimpanan, karena String adalah satu-satunya tipe yang didukung oleh localStorage dan String memang memiliki properti Panjang. Bisakah Anda memposting beberapa contoh di jsfiddle atau yang serupa?
Mihir

1

Sesuai spesifikasi, setiap karakter string adalah 16 bit.

Tetapi memeriksa dengan chrome (Pengaturan> Pengaturan Konten> Cookie & Data Situs) menunjukkan kepada kita bahwa memulai Penyimpanan lokal membutuhkan 3kB (ukuran overhead)

Dan ukuran data yang disimpan mengikuti hubungan ini (akurat hingga 1kB)
3 + ((localStorage.x.length * 16) / (8 * 1024)) kB

di mana localStorage.x adalah string penyimpanan Anda.


0

// Memori ditempati oleh kunci dan nilai jadi Kode yang Diperbarui.

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

Ya, pertanyaan ini ditanyakan seperti 10 tahun yang lalu. Tetapi bagi mereka yang tertarik (seperti saya, karena saya sedang membangun editor teks offline yang menyimpan data dengan penyimpanan lokal) dan payah dalam pemrograman, Anda dapat menggunakan sesuatu yang sederhana seperti ini:

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

Cara terbaik untuk mendapatkan jumlah penyimpanan yang terisi adalah dengan melihat pengaturan situs (misalnya, jika Anda menyimpan gambar di penyimpanan lokal). Setidaknya di chrome, Anda dapat melihat jumlah byte yang digunakan (yaitu: 1222 byte). Namun, cara terbaik untuk melihat penyimpanan lokal yang terisi dengan js telah disebutkan di atas, jadi gunakanlah.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.