localStorage 공간 사용량 계산


80

Bespin 편집기와 HTML5의 localStorage를 사용하여 앱을 만들고 있습니다. 모든 파일을 로컬에 저장하고 문법을 돕고, JSLint 및 CSS 및 HTML에 대한 기타 파서를 사용하여 사용자를 지원합니다.

localStorage 한도가 얼마나 사용되고 실제로 얼마나 많이 있는지 계산하고 싶습니다. 오늘 가능할까요? 나는 단순히 저장된 비트를 계산하는 것이 아니라고 생각하고 있었다. 그러나 나는 내가 스스로 측정 할 수없는 것이 더 있는지 확신하지 못한다.



JavaScript / HTML5 localStorage 유용한 기능 : stackoverflow.com/q/34245593/4339170
CoderPi

답변:


73

JSON 메서드를 사용하여 전체 localStorage 개체를 JSON 문자열로 바꾸면 대략적인 아이디어를 얻을 수 있습니다.

JSON.stringify(localStorage).length

특히 추가 객체를 사용하는 경우 몇 바이트의 추가 마크 업으로 얼마나 바이트가 정확한지 모르겠습니다.하지만 28K 만 푸시하고 대신 280K (또는 그 반대)를 수행한다고 생각하는 것보다 낫다고 생각합니다. 마찬가지로).


4
이것은 실제로 작업하기에 충분히 정확합니다. Chrome 14에서 localStorage를 최대로 사용하면 JSON.stringify (localStorage) .length === 2636625 또는 2.51448MB로 충분히 가깝습니다 ( dev-test.nemikor.com/web-storage/support-test ). try {} catch {}와 함께 사용되며 도우미 클래스를 구축하기에 충분합니다.
Christopher

13
링크하는 테스트에서 지적했듯이 이것은 바이트가 아닌 문자 단위의 크기입니다. "JavaScript의 문자열은 UTF-16이므로 각 문자에는 2 바이트의 메모리가 필요합니다. 이는 많은 브라우저에 5 바이트가 있음을 의미합니다. MB 제한, 250 만 자만 저장할 수 있습니다. "
Mortimer

52

필요한 브라우저의 남은 한도를 얻을 수있는 보편적 인 방법을 찾지 못했지만 한도에 도달하면 팝업 오류 메시지가 표시된다는 것을 알게되었습니다. 이것은 물론 각 브라우저마다 다릅니다.

최대한 활용하기 위해이 작은 스크립트를 사용했습니다.

for (var i = 0, data = "m"; i < 40; i++) {
    try { 
        localStorage.setItem("DATA", data);
        data = data + data;
    } catch(e) {
        var storageSize = Math.round(JSON.stringify(localStorage).length / 1024);
        console.log("LIMIT REACHED: (" + i + ") " + storageSize + "K");
        console.log(e);
        break;
    }
}
localStorage.removeItem("DATA");

그로부터 나는이 정보를 얻었습니다.

구글 크롬

  • DOMException :
    • 코드 : 22
    • 메시지 : " '저장소'에서 'setItem'실행 실패 : '데이터'값 설정이 할당량을 초과했습니다."
    • 이름 : "QuotaExceededError"

모질라 파이어 폭스

  • DOMException :
    • 코드 : 1014
    • 메시지 : "영구 저장소 최대 크기에 도달했습니다."
    • 이름 : "NS_ERROR_DOM_QUOTA_REACHED"

원정 여행

  • DOMException :
    • 코드 : 22
    • 메시지 : "QuotaExceededError : DOM Exception 22"
    • 이름 : "QuotaExceededError"

Internet Explorer, Edge (커뮤니티)

  • DOMException :
    • 코드 : 22
    • 메시지 : "QuotaExceededError"
    • 이름 : "QuotaExceededError"

내 솔루션

지금까지 내 해결책은 사용자가 무엇이든 저장할 때마다 추가 호출을 추가하는 것입니다. 그리고 예외가 잡히면 스토리지 용량이 부족하다고 말할 것입니다.


편집 : 추가 된 데이터 삭제

이것이 실제로 작동하려면 DATA원래 설정된 항목 을 삭제해야한다는 것을 언급하는 것을 잊었습니다 . 변경 사항은 removeItem () 함수를 사용하여 위에 반영됩니다 .


매우 좋습니다. i각 경우에 도달했을 때 의 가치는 무엇 입니까?
artlung

20-21 나는 생각한다. 원하는 경우 직접 테스트를 실행할 수 있습니다.
JeroenEijkhof

IE : ABORT_ERR : 20 코드 : 22 메시지 : "QuotaExceededError"이름 : "QuotaExceededError"
Rui Lima

IE에서 공백이 끝나기 전에 코드에서 예외가 발생합니다. window.localStorage.remainingSpace : 805692 | window.localStorage.getItem ( "DATA"). length : 4194304 | JSON.stringify (localStorage) .length : 4194315 | i : 22
Rui Lima

좋아, 나는 try catch 블록에 로컬 스토리지 코드를 래핑하고 크기 초과시 catch 블록에서 사용자에게 경고 할 수 있습니다.
Nirus

26

IE8 remainingSpace은 이러한 목적으로 속성을 구현합니다 .

alert(window.localStorage.remainingSpace);  // should return 5000000 when empty

불행히도 이것은 다른 브라우저에서는 사용할 수없는 것 같습니다. 그러나 비슷한 것을 구현하는지 확실하지 않습니다.


1
@WmasterJ : IE 팀이 실제로 이것 (또는 비슷한 것)이 표준 (2008 년에 거슬러 올라감 )에 포함될 것을 제안한 것을보고 있습니다 : markmail.org/thread/ugzdcamtyftcyk6y .
Daniel Vassallo

45
이번에는 IE가 맞았습니다. 이것이 필요하다는 것이 분명해 보일 것입니다.
JeroenEijkhof 2010 년

Microsoft는 이것을 이해하지 못합니다. "localStorage 속성은 도메인을위한 영구 저장 영역을 제공합니다.이를 통해 웹 응용 프로그램은 성능상의 이유로 전체 문서 또는 사용자 사서함과 같은 거의 10MB의 사용자 데이터를 클라이언트에 저장할 수 있습니다. " 하지만 마지막에 남은 공간은 5000000 (?!?!)을 반환합니다. 왜?!
Rui Lima

3
@RuiLima, 자바 스크립트의 문자는 1 바이트가 아닌 2 바이트를 사용하기 때문에 5000000자는 실제로 10MB의 공간을 차지합니다. IE가 바이트 대신 남은 문자를보고하거나 저장소 제한에 대해 마음을 바꾼 것처럼 보입니다.
Ishmael Smyrnow 2011

1
이 leftSpace 속성은 localStorage의 오버플로가 예외를 throw 할 것으로 예상하는 경우 중요합니다. IE는 예외를 throw하지 않습니다. 따라서 localStorage에 저장하기 전후에이 속성을 확인해야합니다. 크기가 변경되지 않은 경우 한도를 초과 한 것입니다.
Andy

15

아래 줄을 사용하여이 값을 정확하게 계산할 수 있으며 여기에 사용 설명을위한 jsfiddle 이 있습니다.

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

이 알고리즘을 사용하여 크롬 확장에 사용 된 공간을 결정하고 있지만 JS가 UTF-8 대신 UTF-16 문자열을 사용한다는 또 다른 SO 질문을 읽은 것을 기억합니다. string.length를 수행하여 얻은 바이트 수. 그게 사실인지 아십니까? 그렇다면 코드를 업데이트해야합니다.
Adam Tuttle 2013 년

1
jsfiddle이 내 브라우저 (mac / chrome)에로드되지 않습니다.
Justin

여기에서 여전히 출력을 볼 수 있지만 JSFiddle을 깨뜨린 것처럼 보입니다 !
c24w 2014 년

문자 당 8 바이트 나 그런 식으로 8을 곱할 필요가 없습니까?
George Mauer 2014 년

George,이 예에서는 대부분의 미국 기반 HTML 사이트에서 'Content-Type'메타 태그에 정의 된 UTF-8 문자 집합을 가정합니다. 유니 코드 지원을 고려하려면 여기를 보십시오 mathiasbynens.be/notes/javascript-unicode 또는 빠른 수정은 여기 JS github.com/craniumslows/Countable/commit/…
jas

9

오늘 테스트 (스토리지 할당량 초과) 중에이 문제를 해결하고 솔루션을 준비했습니다. IMO는 한계가 무엇이며 우리가 어디에 있는지 아는 것은 할당량을 초과하여 계속 저장하는 기능적 방법을 구현하는 것보다 훨씬 덜 가치가 있습니다.

따라서 크기 비교 및 ​​용량 확인을 시도하는 대신 할당량에 도달했을 때 대응하고 현재 스토리지를 1/3로 줄인 다음 저장을 재개하십시오. 감소가 실패하면 저장을 중지하십시오.

set: function( param, val ) { 
    try{
        localStorage.setItem( param, typeof value == 'object' ? JSON.stringify(value) : value )
        localStorage.setItem( 'lastStore', new Date().getTime() )
    }
    catch(e){
      if( e.code === 22 ){
        // we've hit our local storage limit! lets remove 1/3rd of the entries (hopefully chronologically)
        // and try again... If we fail to remove entries, lets silently give up
        console.log('Local storage capacity reached.')

        var maxLength = localStorage.length
          , reduceBy = ~~(maxLength / 3);

        for( var i = 0; i < reduceBy; i++ ){
          if( localStorage.key(0) ){
            localStorage.removeItem( localStorage.key(0) );
          }
          else break;
        }

        if( localStorage.length < maxLength ){
          console.log('Cache data reduced to fit new entries. (' + maxLength + ' => ' + localStorage.length + ')');
          public.set( param, value );
        }
        else {
          console.log('Could not reduce cache size. Removing session cache setting from this instance.');
          public.set = function(){}
        }
      }
    }
}

이 함수는 래퍼 개체 내에 있으므로 public.set은 단순히 자신을 호출합니다. 이제 스토리지에 추가 할 수 있으며 할당량이 얼마인지 또는 얼마나 가까운 지 걱정할 필요가 없습니다. 단일 저장소가 할당량 크기의 1/3을 초과하는 경우이 함수가 컬링을 중지하고 저장을 종료하는 위치이며 그 시점에서 캐싱하면 안됩니다.


5

브라우저 테스트 결과에 추가하려면 :

Firefox i = 22.

Mac의 Safari 버전 5.0.4가 중단되지 않았습니다. Chrome 오류입니다. i = 21.

Opera 웹 사이트가 데이터를 저장하려고하지만 충분한 공간이 없음을 사용자에게 알립니다. 사용자는 요청을 거부하거나 한도를 필요한 양 또는 여러 다른 한도까지 거부하거나 무제한으로 설정할 수 있습니다. 이 메시지가 표시되는지 여부를 알려면 opera : webstorage로 이동하세요. i = 20. 발생한 오류는 Chrome과 동일합니다.

Chrome으로 IE9 표준 모드 오류입니다. i = 22.

IE8 표준 모드의 IE9 콘솔 메시지 "오류 :이 작업을 완료하는 데 사용할 수있는 스토리지가 충분하지 않습니다." i = 22

이전 모드의 IE9 개체 오류. i = 22.

IE8 테스트 할 사본이 없지만 로컬 저장소가 지원됩니다 (http://stackoverflow.com/questions/3452816/does-ie8-support-out-of-the-box-in-localstorage).

IE7 이하 로컬 저장소를 지원하지 않습니다.


3

웹 스토리지 지원 테스트로 브라우저를 테스트 할 수 있습니다.

내 Android 태블릿과 Windows 노트북에서 Firefox 를 테스트 하고 Windows 결과에서만 Chromium을 테스트했습니다.

  1. Firefox (Windows) :

    • localStorage : 5120k char
    • sessionStorage : 5120k char
    • localStorage : * 지원되지 않음
  2. Firefox (Android) :

    • localStorage : 2560k char
    • sessionStorage : 무제한 (정확히 테스트 실행 최대 10240k char == 20480k byte)
    • localStorage : 지원되지 않음
  3. Chromium (Windows) :

    • localStorage : 5120k char
    • sessionStorage : 5120k char
    • localStorage : 지원되지 않음

최신 정보

Google Chrome 버전 52.0.2743.116m (64 비트)에서는 5101k문자가 조금 더 낮습니다 . 즉, 사용 가능한 최대 값은 버전에서 변경 될 수 있습니다.


당신은 brobably 5120 의미 K의 문자
Juribiyan

@Juribiyan 네, 그렇습니다.
Morteza Tourani

2

댓글에 추가 할 수 있으면 좋겠습니다. 담당자가 부족합니다. 죄송합니다.

일부 성능 테스트를 실행했습니다. JSON.stringify (localStorage) .length가 대규모 localStorage 점유에서 값 비싼 작업이 될 것으로 예상했습니다.

http://jsperf.com/occupied-localstorage-json-stringify-length

실제로 저장하는 항목을 추적하는 것보다 약 50 배 더 비싸고, localStorage가 더 많아지면 더 나빠집니다.


2

이 기능은 사용 가능한 / 남은 정확한 스토리지를 가져옵니다 .

나는 * 로컬 스토리지에 대한 유용한 기능의 제품군을 만들어 여기 *

http://jsfiddle.net/kzq6jgqa/3/

function getLeftStorageSize() {
    var itemBackup = localStorage.getItem("");
    var increase = true;
    var data = "1";
    var totalData = "";
    var trytotalData = "";
    while (true) {
        try {
            trytotalData = totalData + data;
            localStorage.setItem("", trytotalData);
            totalData = trytotalData;
            if (increase) data += data;
        } catch (e) {
            if (data.length < 2) break;
            increase = false;
            data = data.substr(data.length / 2);
        }
    }
    localStorage.setItem("", itemBackup);

    return totalData.length;
}

// Examples
document.write("calculating..");
var storageLeft = getLeftStorageSize();
console.log(storageLeft);
document.write(storageLeft + "");

// to get the maximum possible *clear* the storage 
localStorage.clear();
var storageMax = getLeftStorageSize();

이것은 매우 빠르지 않으므로 항상 사용하지 마십시오.

이것으로 나는 또한 발견했다 : Item-Name은 그것의 길이만큼 많은 공간을 차지할 것이고, Item-Value는 또한 그들의 길이만큼 많은 공간을 차지할 것입니다.

내가 얻은 최대 저장 용량-약 5M :

  • 5000000 자-Edge
  • 5242880 자-Chrome
  • 5242880 자-Firefox
  • 5000000 자-IE

바이올린에서 주석 처리 된 코드를 찾아 콘솔에서 진행 상황을 볼 수 있습니다.

시간이 좀 걸렸는데 도움이 되었으면 좋겠어요 ☺


2
 try {
     var count = 100;
     var message = "LocalStorageIsNOTFull";
     for (var i = 0; i <= count; count + 250) {
         message += message;
         localStorage.setItem("stringData", message);
         console.log(localStorage);
         console.log(count);
     }

 }
 catch (e) {
     console.log("Local Storage is full, Please empty data");
     // fires When localstorage gets full
     // you can handle error here ot emply the local storage
 }

1

스토리지가 꽉 찼을 때 모듈이 수행 할 작업을 실제로 시뮬레이션하고 테스트해야했기 때문에 수용된 대답이 아니라 스토리지가 가득 차면 i ^ 2의 속도로 정밀도를 잃는 정확한 정확도를 얻어야했습니다.

다음은 메모리 캡에 도달했을 때 항상 10의 정밀도를 생성해야하는 스크립트이며, 몇 가지 쉬운 최적화에도 불구하고 상당히 빠르게 ... 편집 : 스크립트를 더 좋고 정확한 정밀도로 만들었습니다.

function fillStorage() {
    var originalStr = "1010101010";
    var unfold = function(str, times) {
        for(var i = 0; i < times; i++)
            str += str;
        return str;
    }
    var fold = function(str, times) {
        for(var i = 0; i < times; i++) {
            var mid = str.length/2;
            str = str.substr(0, mid);
        }
        return str;
    }

    var runningStr = originalStr;
    localStorage.setItem("filler", runningStr);
    while(true) {
        try {
            runningStr = unfold(runningStr, 1);
            console.log("unfolded str: ", runningStr.length)
            localStorage.setItem("filler", runningStr);
        } catch (err) {
            break;
        }
    }

    runningStr = fold(runningStr, 1);  
    var linearFill = function (str1) {
        localStorage.setItem("filler", localStorage.getItem("filler") + str1);
    }
    //keep linear filling until running string is no more...
    while(true) {
        try {
            linearFill(runningStr)
        } catch (err) {
            runningStr = fold(runningStr, 1);
            console.log("folded str: ", runningStr.length)
            if(runningStr.length == 0)
                break;
        }
    }

    console.log("Final length: ", JSON.stringify(localStorage).length)
}

0

이것은 누군가를 도울 수 있습니다. 크롬에서는 필요한 경우 더 많은 디스크 공간을 사용할 수 있도록 사용자에게 요청할 수 있습니다.

// Request Quota (only for File System API)  
window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) {
  window.webkitRequestFileSystem(PERSISTENT, grantedBytes, onInitFs, errorHandler); 
}, function(e) {
  console.log('Error', e); 
});

자세한 내용은 https://developers.google.com/chrome/whitepapers/storage#asking_more 를 방문 하세요 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.