웹 로컬 데이터 저장소의 비교

조경석·2023년 3월 26일
0

Web Storage API, IndexedDB는 서버 측 DB를 별도로 사용하지 않고도 사용자 개별 정보를 활용할 수 있도록, 클라이언트의 브라우저에 데이터를 로컬 저장하기 위해 만들어졌다.
단순히 DB를 제공할 수 없는 환경 뿐 아니라, 데이터 작업을 서버로 왕복하는 불필요한 처리를 최소화해 클라이언트에서 자체적으로 저장, 색인할 수 있는 효율성을 위한 기능이기도 하다.

Web Cookie API와 HTML5 로컬 저장소의 비교

1994년에 넷스케이프에서 도입한 이후 모든 브라우저에서 표준적으로 사용하게 된 HTTP 요청 기반의 Web Cookie API(이하 쿠키)와는 달리, Web Storage API(2009년)와 IndexedDB(2010년)는 HTML5 사양으로 도입되었으며 클라이언트 브라우저에서 독립적으로 로컬 데이터를 색인, 관리하는 기능을 목표로 만들어졌다.

쿠키의 경우 모든 HTTP 요청과 함께 자동으로 서버로 전송되고, 상위 도메인이 동일하다면 모든 스크립트에서 접근 가능하다는 보안 취약점이 있지만 HTML5 로컬 저장소의 경우 해당 저장소를 생성한 자바스크립트에서만 접근이 가능하고, 서버로 전송될 필요 없이 클라이언트의 JS 코드상에서만 처리된다.

모든 쿠키 데이터는 자체적으로 수명을 지정하고, 4KB 미만의 소량의 데이터를 저장하기 위해서만 사용되지만 HTML5 로컬 저장소의 경우 영구적으로 대량의 데이터를 저장하기 위해 사용된다.

Web Storage API

JS Window 객체의 읽기 전용 속성 .localStorage와 .sessionStorage를 사용하며, window.~의 형태가 아닌 localStorage, sessionStorage 이름 자체로도 접근 가능하다.
읽기 전용 속성이므로 localStorage, sessionStorage 객체 자체를 수정할 수 없고 메서드를 사용하거나 직접 객체의 키, 값을 추가, 변경할 수 있다.
페이지의 프로토콜 단위로 Storage를 구분하므로, 동일한 페이지로 보이더라도 HTTP 페이지와 HTTPS가 존재하는 경우 별개의 Storage로 저장된다.

참고로, Chromium 계열 브라우저의 개발자 도구에서는 저장된 Web Storage API의 데이터가 제대로 표시되지 않는 버그가 있다.
링크의 이슈 이전에도 자주 보고된 유서깊은 버그인만큼 수정 이력도 자주 있었지만, 링크에서도 2023년 2월자 경험 보고와 개인적인 해결방안이 댓글로 달릴 정도로 아직 완전히 해결되지 않은 이슈이다.
개발 중 검증을 필요로 하는 경우 콘솔에서 Web Storage API 객체를 직접 호출하는 편을 추천한다.

window.localStorage

window.localStorage(이하 localStorage)는 Web Storage API 중 영구적으로 데이터를 저장하기 위한 속성이다.
직접적으로 삭제되기 전까지는 만료되지 않으며, localStorage.clear() 메서드로 해당 Origin을 출처로 하는 모든 localStorage를 삭제할 수 있다.
영구적인 데이터를 목적으로 하지만, 대부분의 브라우저에서 제공하는 사생활 보호 브라우징 기능을 적용할 경우 창의 마지막 탭이 닫히면 사생활 보호 상태에서 조회한 모든 localStorage 데이터가 삭제된다.

window.sessionStorage

window.sessionStorage(이하 sessionStorage)는 Web Storage API 중 세션(을 닫기 전)내에서 데이터를 저장하기 위한 속성이다.
세션이 만료되기 전까지 데이터를 유지하므로 페이지가 새로고침된 경우에도 데이터가 유지되며, 이를 활용해 의도하지 않은 새로고침이 일어날 수 있는 페이지에서 사용자 입력값을 보존하기 위해 사용할 수 있다.
대부분의 브라우저에서 제공하는 닫은 탭 복구 기능을 사용하면 sessionStorage 역시 복구되지만, 해당 데이터는 복구 시에만 적용되어 복구 데이터가 유지된 상태에서 별도의 세션에서 동일한 페이지에 접근한다고 해도 기존 sessionStorage 데이터가 사용되지는 않는다.

IndexedDB

IndexedDB는 Web Storage API에 비해 구조화된 데이터를 저장하고 보다 최적화된 인덱싱을 위한 트랜잭션 데이터베이스 시스템이다.
네트워크 상태에 상관없이 동작 가능하므로 오프라인 대규모 데이터를 기반으로 동작하는 웹 어플리케이션을 구성하는데 사용할 수 있다.
일반적인 관계형 데이터베이스에서 사용하는 고정 컬럼 테이블을 사용하지 않고, JS를 기반으로 하는 객체지향 DB이므로 데이터를 Index Key를 통해 저장, 색인한다.
Web Storage API과 가장 큰 차이점은 데이터를 비동기로 처리한다는 것으로, 일반적으로 데이터를 색인, 수정하는 Transaction을 시행한 후 DOM 이벤트 리스너를 통해 요청이 완료된 후 처리하는 방식을 사용한다.

추가 : 로컬 저장소 한계 용량 초과시 어떻게 되는가

위 단락까지는 대부분 웹에서 쉽게 찾을 수 있는 내용이지만 글 정리를 위해 이것저것 알아보다 꽤 흥미로운 글을 찾았다.

일반적으로 '쿠키는 4KB 미만의 소량의 데이터를 관리하기 위해 사용한다'고만 하지 그 용량이 왜 4KB인지, 초과하면 어떻게 되는지에 대한 내용은 정리되지 않는다.
글의 주제는 HTML5 로컬 저장소지 쿠키가 아니므로 간략하게 정리하면 4KB라는 것은 개별 쿠키의 용량이고, 1994년 넷스케이프에서 정한 한계의 호환성을 유지할 뿐이고(90년대 중반을 넘어서야 하드 디스크를 포함한 저장소 용량이 GB 단위에 진입했다.), 4KB를 초과하면 단순히 브라우저가 해당 쿠키를 무시해 저장하지도, 서버로 전송하지도 않는다.

그렇다면 일반적으로 Web Storage API의 용량 한계라고 말하는 약 5MB 역시 도메인 단위인데, 이를 초과하면 어떻게 되는지 확인해본 글이 있었다.
꽤 오래 전의 글이지만 결론만 보면 브라우저는 절대로 정확한 한계 용량값을 보장하지 않으며, 저장소 용량이 일정 수준을 초과하는 순간 에러를 throw해준다.
당연히 댓글에서 싸우고 있는 내용대로 이 때문에 Web Storage API를 사용할 때 try/catch를 시행해야 할 필요까지는 없다.

IndexedDB에서도 유사한 결과를 보이지만, Web Storage API와는 다르게 도메인 단위의 제한을 사용하지 않고 Quota(몫)이라고 명명된 브라우저 저장 공간을 사용한다.

비교적 최근(2020년)의 글에서 로컬 저장소에 대한 상세한 정리와 함께 Quota(몫)에 대한 정보를 찾을 수 있었다.
크롬 브라우저의 경우 디스크 용량을 기준으로 Quota를 산정하며, 파이어폭스의 경우 기본값이 설정되어 있다.
위 링크의 본문에서 로컬 저장소 테스트 도구를 같이 제공하는데, 브라우저의 개발자 도구의 저장소 창에 대해서 이것저것 테스트해보려는 경우에 유용할 것 같다.

1개의 댓글

comment-user-thumbnail
2023년 4월 11일

안녕하세요, 제로베이스 프론트엔드스쿨 멘토입니다. 작성해주신 글 잘 읽었고, 앞으로의 더 나은 블로깅을 응원하는 마음에서 작은 의견을 남기고 갑니다 :)

  • 첫번째 소제목인 'Web Cookie API와 HTML5 로컬 저장소의 비교'를 정확성을 높이기 위해 'Web Cookie API와 HTML5 Web Storage의 비교'로 살짝 수정해주는 것도 좋을 것 같습니다.
  • 전체적으로 내용상의 오류 없이 잘 작성해주셨습니다.
  • 또한 글의 구성과 스타일을 잘 잡아주셔서, 가독성이 좋고 읽기가 편했습니다.
  • 여유가 되신다면, 각 저장 방식을 적용하기 위한 실제 샘플 코드도 작성해서 추가해보시고, 코드 측면에서의 문법적인 차이점도 학습하고 비교해보시면 좋을 것 같습니다.
  • 마지막에 기본적인 개념 외에도 추가로 학습하신 부분, 흥미롭다고 생각하고 더 알아보신 부분이 인상깊었습니. 개발자의 기본 소양이 호기심과 학습에 대한 의지인데 이를 드러낼 수 있는 부분인 것 같았습니다.

감사합니다!

답글 달기