[브라우저] Application/Storage 탭 구경하기

@eunjios·2024년 3월 28일
1
post-thumbnail

쿠키와 로컬 스토리지, 세션 스토리지
그래서 어떻게 쓰이나요? 🤔

이커머스는 무엇을 브라우저에 저장할까?

라는 마음으로 마켓컬리 스토리지를 뜯어보게 되었다. 왜 하필 마켓컬리냐 묻는다면 할 말은 없지만 실제로 많이 사용하는 서비스기 때문이다.

장바구니 아이템 유지하기

마켓컬리

마켓컬리는 로그아웃 상태일 때도 장바구니 아이템이 유지된다. 브라우저를 종료하고 다시 들어와도 동일한 아이템이 유지된다. 그리고 다시 로그인을 하게 되면 기존 장바구니 아이템은 로그인 상태의 장바구니 아이템에 추가된다. 다시 로그아웃 하면 카트는 빈 상태가 된다.

다음은 Application 탭의 로컬 스토리지 탭과 쿠키 탭이다.

로컬 스토리지 탭

쿠키 탭

마켓컬리는 로그인 상태가 아닐 때 장바구니 아이템을 로컬 스토리지에 저장하고 있다. 그래서 브라우저가 종료되어도 해당 데이터가 유지된 것이다. 반면 장바구니에 담긴 아이템 개수는 쿠키에 저장하고 있다. Expires / Max-Age 파라미터가 없으므로 브라우저를 닫으면 삭제되는 세션 쿠키다.

응답 메시지의 Set-Cookie 헤더에 쿠키가 있으면 이를 클라이언트 측에 저장한다. (또는 클라이언트가 직접 쿠키를 생성할 수도 있다.) 그리고 미래에 같은 사이트를 방문하면 저장된 쿠키는 요청 메시지의 Cookie 헤더에 담겨 서버로 보내지게 된다.

Application - Storage - Cookies 탭에서 해당 쿠키를 포함하는 요청들도 볼 수 있다. 아래의 cart_count 는 도메인이 .kurly.com 이므로 같은 도메인의 요청들에는 모두 cart_count가 포함된다.

근데 왜 아이템 개수만 쿠키로 따로 저장하는지 모르겠다. 도대체 왜 ? 🤔 모든 요청에 카트 카운트를 보내야 하는 이유는 ? 뭘까 ? 아시는 분 댓글 주세요 . .


아무튼 이제 로그인을 해보자. 로그인 후 Local storage 탭을 확인하면 cartItems 가 사라진 것을 확인할 수 있다.

로그인에 성공하면 로컬 스토리지를 확인하여 저장된 cartItems 가 있는지 확인한다. 만약 저장된 cartItems 가 있다면 이를 로그인 유저의 서버 사이드 데이터에 추가하고 기존 로컬 스토리지의 데이터는 삭제해야 할 것이다.

Network 탭을 확인하면 예상한대로 동작한다. 로그인 후에 POST 메서드의 sync 통신이 실행되는데 해당 페이로드에 로그아웃 상태에서 담았던 아이템 두 개 (로컬 스토리지에 저장되어 있던 cartItems) 가 함께 보내지는 것을 확인할 수 있다.

또한 응답 결과의 cartItems 는 다음과 같다. 인증된 유저의 기존 데이터에 로컬 스토리지 데이터 (인덱스 0, 1) 가 추가된 것을 확인할 수 있다.


쿠팡

다른 서비스는 어떻게 카트 아이템을 유지하고 있을지 궁금해서 쿠팡도 확인해 봤다. 쿠팡의 로컬 스토리지는 카트 아이템과 관련된 프로퍼티가 없었고, 세션 스토리지도 비어있었다. 쿠키에는 여러 아이디 정보나 검색 키워드 등이 저장되어 있었다. 즉, 장바구니 관련 데이터는 서버 측에서 관리하고 있는 것으로 보였다.

장바구니에 상품 개수까지 모두 클라이언트 측에는 저장되어 있지 않다. 네트워크 탭을 확인해 보면 다음과 같이 cartCount?callback=jQuery~~~ 와 같은 URL에 리소스 요청을 보내고 있는 것을 볼 수 있다.

callback=jQuery... 는 무엇인가 찾아보니 JSONP 방식을 사용한 요청 방식이라고 한다. (JSONP 관련 내용은 이 포스트를 참고하자 : CORS와 JSONP에 대해서) 간단히 말하면 JSONP는 CORS가 나오기 전 다른 도메인에 비동기 요청을 하기 위해 쓰인 방법이다. 서버에서 값을 가져오기 위해서는 콜백 함수가 필요하고, 이 콜백 함수를 URL에 포함시켜서 넘겨줘야 한다.

요청을 보내면 이렇게 해당 콜백 함수에 요청한 값을 포함시킨 response 가 온다. 여기서 productCountInCart 라는 값을 추출하면 현재 카트에 담긴 아이템 수를 받아올 수 있는 것이다.

어쩌다 보니 JSONP 방식까지 오게 되었지만 핵심은 쿠팡은 서버에서 장바구니 상품을 저장한다는 것이다. 그래서 실제로 장바구니에 담은 후 아이템 숫자가 즉각적으로 올라가는 것이 아니라 살짝의 딜레이가 있다.


최근 본 아이템

마켓컬리는 최근 본 아이템을 로컬 스토리지로 관리한다. 그래서 로그인이 되어 있든, 되어있지 않든 동일한 최근 본 아이템을 제공한다.


N일 동안 안 보기 버튼

마켓컬리는 팝업창을 닫기 위한 버튼으로 '닫기' 버튼과 '오늘 하루 안 보기' 버튼이 있는데, 오늘 하루 안 보기 버튼을 누르면 로컬 스토리지의 mainNotice 배열에 추가된다.

이렇게 보여지지 않을 팝업창을 로컬 스토리지에서 저장하고 있다.


장바구니 내부 아이템 선택 여부 저장

이것도 역시 cartCheckbox 라는 이름으로 로컬 스토리지에 저장되어 있다. 각 아이템마다 체크 여부가 boolean 형태로 저장된다. 이 기능은 로그인 상태일 때만 유효한 기능이다.

유저 아이디: {
  상품 아이디 : true,
  상품 아이디 : false,
}

위와 같은 형태로 저장되어 있다.


최근 검색어 기록

최근 검색어는 대부분 로컬에 저장한다.

  • 서버가 접근해야 하는 데이터인가? → X
    이미 검색할 때마다 데이터는 쌓일테니 중복으로 데이터를 사용할 필요가 없다. 즉 쿠키로 저장할 필요가 없다.
  • 브라우저를 종료해도 유지되어야 하나? → O
    사용자 경험 측면에서 좋은 선택이다.

브라우저를 종료해도 검색 내역을 유지할 수 있고, 또 서버측 부담도 줄일 수 있으니 이건 확실히 좋은 선택인 듯


마무리

이렇게 Application 탭 구경을 소소하게 마친다. 마켓컬리는 로컬 스토리지를 적극적으로 사용하고 있었고, 쿠팡은 대부분 서버 측에서 데이터를 관리하고 있었다. 그리고 최근 검색어 기능은 대부분의 서비스가 로컬에 저장한다.

개념만 알고 있을 때보다 실제로 어떻게 쓰이는지를 확인해 보니 이해도가 더 높아졌다. 실제 페이지를 뜯어보기 전까지는 둘 다 사용할 수 있는거 아닌가? 라는 마음으로 답답한 느낌이 들었는데 그게 맞았다. 실제 서비스들도 다양한 방식으로 스토리지나 쿠키를 사용하고 있었고, 각각의 장단점이 있을 뿐 딱 정해진 답은 없다. 서비스나 데이터의 특징에 따라 또 보안 수준에 따라 다양한 선택지가 있기 때문에 앞으로도 더 고민해 보면 좋겠다.


고민해 볼 토픽

Local Storage or Cookies for Shopping Cart Items?

카트 아이템 데이터로 로컬 스토리지를 사용하냐 쿠키를 사용하냐에 대한 논의다. 로컬 스토리지를 사용하는 경우가 두 배 이상 많았다.

로컬 스토리지

  • 로그인 되지 않은 상태에서 로컬 스토리지를 사용하고 로그인 된 경우 백엔드에서 관리하는 것이 좋음
  • 카트 아이템 모두 (id, count 등)를 저장할 경우 로컬 스토리지에 저장

쿠키

  • 카트 아이템 모두를 저장하는 것이 아니라 카트 아이디만 저장하는 방식으로 동작하는 경우, 카트 아이디만 쿠키에 저장하고 DB에 카트 아이템들을 저장
  • abandoned 카트 아이템은 유의미한 데이터이므로 DB에 저장하는 것이 가치 있음

What to store in state vs Local storage or Session?

브라우저의 스토리지를 단지 전역 데이터 관점에서만 보면 state를 두고 왜 사용하지 라는 의문이 든다. state는 새로고침 하면 사라지는 데이터지만 로컬 스토리지나 세션에 저장된 값은 유지되는 데이터라는 것이 큰 차이다.

로컬 스토리지

  • 브라우저 창을 닫아도 유지되는 데이터를 저장

세션 스토리지

  • 새로고침 해도 유지되는 데이터를 저장
  • 브라우저 창을 닫으면 삭제됨

state

  • 위 경우가 아니라면 모두 state에 저장
  • 새로고침 하면 사라지는 데이터
  • 브라우저 API를 최소한으로 사용하는 것이 좋다는 의견도 있음
profile
growth

0개의 댓글