밝을희 클태

cache에 대해서 본문

KEYNUT 프로젝트

cache에 대해서

huipark 2024. 6. 30. 15:51

 프로젝트를 진행하다가 상품 업로드를 하고 상품을 조회할 때 옛날의 데이터가 미리 렌더링 되고 그 이후에 최신 데이터로 바뀌는 게 너무 별로라서 왜 그런지 궁금했다.

새로고침이 일어나면 이전 데이터를 보여주고 새로운 데이터를 보여줌

 일단 상품을 렌더링 하는 로직이

const getProducts = async queryString => {
...
    const res = await fetch(url);
...
};

export default getProducts;
  • 서버 사이드에서 react query를 사용해서 data prefetching(getProduct)
  • 클라이언트 사이드에서 useQuery를 사용해 서버에서 미리 받아온 데이터를 렌더링
  • react query 내부적으로 백그라운드에서 데이터 재검증이 일어나 최신 데이터를 다시 렌더링

 

 원인은 위에 로직을 봐서 알겠지만 서버 사이드에서 fetch 캐시 전략이 설정이 되어 있지 않아 기본으로 force-cache가 설정이 되어있다.

 force-cache: Next.js Data Cache에서 일치하는 항목을 찾고, 일치하는 항목이 있고 최신이면 해당 캐시를 반환하고, 일치하는 항목이 없고 최신이 아니면 네트워크 요청을 통해 새로운 데이터를 받은 다음 캐시 업데이트를 한 뒤 데이터를 반환한다.

 

여기서 최신 데이터라는 게 DB에 저장된 최신 데이터가 아닌 Next.js 서버에 저장된 데이터 캐시가 최신인지 아닌지를 뜻한다. 서버 사이드에서 fetch의 캐싱 전략을 default(force-cache)로 두고 따로 재검증 로직이 없으면 첫 캐시 된 데이터가 영원히 바뀌지 않고 같은 데이터를 주기 때문에 조심해야 한다.

 

캐싱 전략을 변경을 해주면 초기 렌더링시 깔끔한 초기화면을 만날 수 있다.

fetch(url, { cache: 'no-store' });

 no-store: Next.js의 서버에 Data Cache를 확인하지 않고 무조건 네트워크 요청으로 데이터를 반환하고, 캐시를 업데이트하지 않는다.

 

하지만 no-store는 항상 최신 데이터를 가져와야 하기 때문에 서버에 부담이 갈 수 있다. 서버의 데이터가 바뀔 때 선택적으로 재검증을 할 수 있는 revalidateTag, revalidatePath와 시간을 기반으로 재검증을 할 수 있는 revalidate를 사용할 것을 추천한다.