본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


앵귤러, 리엑트, 뷰/뷰(Vuejs)

[VUEJS] Nuxtjs에서 캐싱 환경에서 호이스팅 그리고 세션 쿠키

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2024. 12. 12.

 

자바스크립트에서의 기본 특성 중 호이스팅(hoisiting)이 있습니다.

해당 기능은 변수나 함수 선언을 코드의 최상단으로 끌어올리는 것처럼 동작하는 특성을 말합니다. 

이는 자바스크립트 엔진이 코드를 실행하기 전에 변수와 함수 선언을 메모리에 저장하는 방식 때문에 발생합니다.

마찬가지로 nuxtjs환경에서의 개발도 이러한 호이스팅 기능에 의해 영향을 받습니다.

 

SSR 환경으로 nuxtjs를 동작시키게 되는 경우 일반적으로 세션 쿠키를 주로 사용하게 됩니다.

마찬가지로 상태 관리 라이브러리인 pinia 또한 persist값을 사용하게 되는 경우 세션 쿠키를 사용 합니다.

 

넉스트(nuxtjs) 환경에서 개발을 하면서 조금 특별하고 잊지 말아야할 부분이 있어서 기록을 해 봅니다.


1. 캐싱 환경에서의 호이스팅

아래와 같은 코드가 존재 합니다.

#case1 : 정상적인 코드

//vue-query 기능
const { refetch, data } = useQuery({
  queryKey: ["querykey"],
  queryFn: async () => {
    const params = {
      method: "get",
      query: {
      },
    };
    return await fetch("api주소", params);
  },
  select: function (data) {
    paging.totalPages = ??;
    paging.currentPage = ??;
    return data;
  },
});

//샘플 reactive 객체
const paging = reactive({
  totalPages: 0,
  currentPage: 1,
  showBottomPages: 10,
  size: 10
});

위 코드는 뷰 쿼리에 의해서 데이터가 조회가 된 뒤에(select) paging이라는 객체의 페이징 정보 값을 바꾸는 코드 입니다.

실제로 해당 코드를 동작 해 보면 이상없이 잘 동작하지만 몇가지 조건을 추가하면 당황스러운(?) 장면을 만나게 됩니다.

 

#case2 : 10초 캐싱을 준 코드

//vue-query 기능
const { refetch, data } = useQuery({
  queryKey: ["querykey"],
  //생략..   
  staleTime: 1000 * 10,  /////여기에 캐싱 10초를 부여 해 봅니다!!
  select: function (data) {
    paging.totalPages = ??;
    paging.currentPage = ??;
    return data;
  },
});

//샘플 reactive 객체
const paging = reactive({
  totalPages: 0,
  currentPage: 1,
  showBottomPages: 10,
  size: 10
});

10초의 캐싱을 부여한 뒤에 해당 코드가 동작을 시키면 처음에는 잘 나오지만 해당 코드가 적용된 페이지에 10초가 지나기 전에 다시 돌아가게 되는 경우, useQuery에서 구조할당한 data 값 undefined 로 나오게 되는 것을 볼 수 있습니다.

어떠한 방법을 추가하더라도 해당 현상은 계속해서 발생하게 됩니다.

그러나 만약 select 함수에서 다른 어떠한 행동을 하지 않는 다면 위 현상은 발생하지 않습니다.

이러한 상황에서 버그(bug)라고 하기 보다는 조건에 따른 케이스라 생각하였기에 대입하는 값에 대해서 여러 방법을 추가해 보기로 하였습니다.

먼저 settimeout으로 이벤트루프에 보내는 구간을 더한 코드 입니다.

 

#case3 : 10초 캐싱 부여 및 타임아웃이 존재하는 코드

//vue-query 기능
const { refetch, data } = useQuery({
  queryKey: ["querykey"],
  //생략..
  staleTime: 1000 * 10,  /////여기에 캐싱 10초를 부여 해 봅니다!!
  select: function (data) {
    setTimeout(() => {  //타입아웃을 부여해봅니다.
      paging.totalPages = ??;
      paging.currentPage = ??;
    }, 1);
    return data;
  },
});

//샘플 reactive 객체
const paging = reactive({
  totalPages: 0,
  currentPage: 1,
  showBottomPages: 10,
  size: 10
});

해당 코드를 동일한 조건에서 실행 해 보면 이상없이 잘 동작하게 됩니다.

useQuery가 존재하는 페이지에 왔다가 다른 페이지로 이동한 뒤 10초가 되기 전에 돌아와도 아까 보았던 undefined 현상이 발생하지 않게되는 것을 볼 수 있습니다.

타임아웃을 더해서 이벤트루프에 들어갔다는 사실만으로 "순서" 에 대한 의심이 생겼습니다.

그래서 해당 코드에서 타임아웃을 제거하고, paging이라는 객체를 맨 위로 올려 보았습니다.

 

#case4 : 10초 캐싱 부여 및 select에서 대입하는 객체를 useQuery 위로 보낸 코드

//샘플 reactive 객체를 맨 상단으로....
const paging = reactive({
  totalPages: 0,
  currentPage: 1,
  showBottomPages: 10,
  size: 10
});

//vue-query 기능
const { refetch, data } = useQuery({
  queryKey: ["querykey"],
  //생략..
  staleTime: 1000 * 10,  /////여기에 캐싱 10초를 부여 해 봅니다!!
  select: function (data) {
    paging.totalPages = ??;
    paging.currentPage = ??;
    return data;
  },
});

역시나 10초캐싱을 준 코드이지만 10초 이내 해당 페이지에 다시 돌아오더라도 이상없이 동작하는 것을 볼 수 있습니다.

그래서 내린 결론이 바로 캐싱 환경에서의 순서(order)의 중요성 입니다.

select 함수가 동작 할 때 const paging으로 선언한 객체가 캐싱환경이 아닌 일반 환경에서는 호이스팅이 정확하게 동작을 하지만,

캐싱환경인 경우에는 마치 코드 한개 한개가, 블록 스코프인 경우 처럼 코드가 동작하여 paging 객체를 찾지 못하여 코드 전체에 영향을 준다는 점 입니다.

그러므로 캐싱 환경에서는 이러한 객체와 함수 선언의 순서가 매우 중요하다고 생각 합니다.


2. SSR 에서 세션 쿠키

일반적으로 nuxtjs 환경에서는 세션쿠키를 사용하여 로그인정보나 권한 또는 기타 행동을 기록하게 됩니다.

특히 SSR 환경에서 pinia를 통해서 상태관리를 하는 경우 persist 값을 따로 주지 않게되면 새로고침(F5, refresh) 한방에 모든 데이터가 사라지기 때문에..거의 대부분 세션 쿠키를 사용하여 정보를 기록 합니다.

 

여기서 매우 주의해야 될 점은 "웹 브라우저의 최대 쿠키 크기는 도메인당 대략 4KB" 라는 점 입니다.

아무 생각없이 세션 쿠키에 데이터를 이것저것 넣게 되는 경우(SSR 환경에서 pinia의 상태에 데이터를 넣는 것도 포함) 메모리에 데이터는 존재 하지만 페이지를 새로 고치거나 새로운 탭으로 페이지를 추가하게 되는 경우, 메모리에 기록한 데이터는 날라가고 세션쿠키를 참조하여 상태를 다시 만들어와야 하는 부분이 세션쿠키가 없기 때 문에 처음엔 동작하지만 새로고침 한번에 모든 것이 동작 안하는 결과를 만날 수 있습니다.

 

더욱이 pinia세션쿠키를 통해서 4KB가 넘는 정보를 저장하더라도 "오류"를 따로 발생시키지 않아서 버그 찾기가 매우 어려워 집니다.

그러므로 세션쿠키 및 pinia에서의 상태 관리는 정말 필요한 정보만 기록하도록 전략을 수립해야 합니다.

정말 간단한 위주, 간결한 위주의 정보만 기록해야 합니다.

 


 

이상으로 Nuxtjs에서 캐싱 환경에서 호이스팅 그리고 세션 쿠키의 이슈에 대해서 간략하게 정리 해 보았습니다.

틀린부분 또는 다른 의견은 언제든 환영합니다!

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글