localStorage와 sessionStorage의 차이점에 대해서 설명해주세요.

ChoiYongHyeun·2025년 1월 2일
0

브라우저

목록 보기
14/16


WebStorage

두 개의 스토리지 모두 브라우저들이 자체적으로 제공하는 다양한 API 중 하나인 WebStorage 객체의 일부이다.

WebStorage 는 브라우저에서 키/값 쌍을 쿠키보다 훨씬 직관적으로 저장 할 수 있는 방법을 제공하기 위해 존재한다.

Storage 인스턴스로 생성된 WindowLocalStorage, WindowSesseionStorage 객체는 window.localStorage, window.sessionStorage 를 통해 조회하거나 수정 하는 것이 가능하다. [1]

localStorage, sessionStorage 의 공통점

키/값 쌍의 타입

Storage 인스턴스는 키/값 형태로 저장 가능하며 저장 되는 값은 항상 문자열이여야 한다.

문자열이여야 하는 이유는 브라우저간 숫자, 배열, 객체 등을 다루는 동작 방식이 달라 호환성 문제를 야기 할 수 있기도 하고

다른 스레드, 혹은 네트워크 간 통신에서 사용 되는 데이터의 타입이 문자열이기 때문이다.

이에 스토리지에서 객체나 배열 등의 값을 저장하기 위해선 JSON.stringfy 를 통해 직렬화 하여 저장하고, JSON.parse 를 통해 객체 형태로 변환하여 조회 해야 한다.

// 객체를 JSON 문자열로 변환하여 저장
const user = { name: '홍길동', age: 30 };
localStorage.setItem('user', JSON.stringify(user));

// 저장된 JSON 문자열을 다시 객체로 변환
const storedUser = JSON.parse(localStorage.getItem('user'));

저장 가능 용량

브라우저마다 스토리지에 저장 가능한 용량이 다르나 각 스토리지 당 과도한 메모리 할당 문제를 피하기 위해 저장 공간이 최소 5MB, 최대 10MB 로 제한 된다.

쿠키스토리지에 비하면 무지막지하게 큰 값이긴 하다. 쿠키스토리지는 고작 4KB 밖에 저장하지 못한다.

스토리지의 범위

origin

두 스토리지들은 동일한 origin 을 가진 페이지에서 사용 가능하다.

브라우저는 origin 별로 WebStorage 세션을 생성하여 origin 별로 독립적인 저장 공간을 생성한다.

예를 들어 http://www.naver.com 에서 로컬 스토리지에 저장된 값은 http://www.naver.com/blahblah... 등 모든 곳에서 가능하지만 http://www.daum.net 에서는 사용 불가능하다.

localStorage, sessionStorage 의 차이점

스토리지의 범위

브라우저와 탭

두 스토리지들은 우선 공통적으로 동일한 origin 을 가진 페이지에서 사용 가능하다는 공통점이 있으나

localStorage 는 동일한 브라우저라면 서로 다른 탭에서도 사용 가능하지만 seesionStroage 는 동일한 브라우저 + 개별 탭 에서만 사용 가능하다는 차이점이 존재한다.

스토리지의 생명 주기

localStorage 의 생명주기는 사용자가 직접 값을 제거하지 않는 이상 제거 되지 않는다.

하지만 seesionStorage 는 사용자가 해당 탭을 닫는 순간 모든 값이 초기화 된다.

특징localStoragesessionStorage
데이터 유지 기간브라우저를 닫아도 유지탭 또는 창을 닫으면 삭제
접근 범위동일한 origin을 가진 모든 탭에서 공유동일한 동일한 탭 또는 창에서만 사용 가능
사용 용도사용자 설정 정보, 캐시 데이터 등 오랫동안 유지해야 하는 데이터 저장임시 데이터, 로그인 상태 등 세션 동안만 유지해야 하는 데이터 저장

서로 다른 사용 용도

위에서 보았듯 두 스토리지의 범위와 생명주기가 다른데 이는 사용 용도가 서로 다르기 때문이다.

개발자가 직접 사용 용도에 따라 적절한 스토리지를 이용하면 되겠지만

보편적인 경우로 로컬 스토리지는 생명주기가 길기 때문에 오랫동안 유지 되어야 하는 데이터면서 탭,창 별로 스토리지 값이 공유되기 때문에 공통적으로 모든 요소에 적용 되어야 하는 값들을 사용하고

세션 스토리지 같은 경우엔 짧은 생명주기, 작은 범위에 해당하는 데이터들을 사용하면 될 것이다.

Storage changeEvent

window.onStorage 혹은 window.addEventListener('storage', callback) 을 통해 스토리지의 변화를 감지하는 이벤트 핸들러를 달 수 있다.

다만 해당 이벤트 핸들러는 서로 다른 탭이나, 창에서 변경이 감지 되었을 때 에만 실행 된다. (동일한 origin 이란 것은 항상 유효하다.) [2]

그럼 사실상 스토리지 체인지 이벤트는 로컬 스토리지에 대해서만 감지 가능한 것으로 볼 수 있다.

같은 탭에서 변화를 감지하지 못하도록 하는 이유는 변경이 일어난 창에서 마저 자신의 변화를 감지하게 된다면 무한 루프에 빠질 수 있어 성능 저하를 야기 할 수 있기 때문이라고 한다.

// 다크 모드 토글 함수
function toggleDarkMode() {
  // 다크 모드 토글 로직 (CSS 클래스 변경 등)
  document.body.classList.toggle('dark-mode');

  // localStorage에 다크 모드 설정 저장
  localStorage.setItem('isDarkMode', !isDarkMode);
}

// storage 이벤트 핸들러
window.addEventListener('storage', () => {
  // localStorage에서 값을 가져와서 UI 업데이트
  const isDarkMode = localStorage.getItem('isDarkMode') === 'true';
  document.body.classList.toggle('dark-mode', isDarkMode);

  // 여기서 문제가 발생할 수 있습니다!
  // 만약 localStorage에 저장된 값이 변경되었다면,
  // 다시 toggleDarkMode 함수를 호출하여 다크 모드를 토글하려고 할 수 있습니다.
  // 이렇게 되면 무한 루프에 빠지게 됩니다.
  toggleDarkMode();
});

잼민이 피셜 이런 예시를 들고 왔는데 사실 나는 잘 이해가 가지 않는다. 이런식이라면 모든 이벤트 리스너가 자기 참조로 인한 무한 루프의 가능성이 존재하는거 아닌가.. ? 만약 무한 루프에 빠질 가능성이 있는 좋은 어떤 예시가 있다면 댓글로 알려주면 좋겠다. 🥹

예시가 적절하지 않더라도 공식문서 스펙상 StorageChange 이벤트는 서로 다른 탭이나 문서에서 변경한 이벤트 시에만 발생하는 것은 맞다.

StorageChange 이벤트 예시 사이트

친절하게도 MDN 에선 StorageChange의 이벤트가 서로 다른 창이나 탭에서 감지 가능한 사이트를 제공한다.[3]

서로 다른 창임에도 불구하고 origin 이 같기 때문에 로컬 스토리지의 변경을 감지하는 모습을 볼 수 있다.

출처

  1. Web Storage API - Web API | MDN
  2. StorageEvent - Web API | MDN
  3. Web Storage API example
profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글