개요Request MemoizationRequest Memoization 막기Data CacheRevalidateTime-based RevalidationOn-demand RevalidationData Cache 막기Full Route CacheClient-side Router CacheReference
현재 작성중인 글입니다
개요
Request Memoization
Request Memoization은 하나의 route를 렌더링 할 때(React component tree를 모두 렌더링 할때 까지) 이루어지는 request중 동일한 path로 이루어지는 여러 요청이 있다면, 한번만 실제로 request 한 후, 나머지는 캐싱하여 전달한다.
이는 캐싱 전략이기도 하지만,
Context
나 global state 관리 없이도 prop drilling을 방지하여, 코드를 좀더 간결하게 짤 수 있게 도와주는 역할을 하기도 한다.그렇기에 caching 보다는 deduping에 가까운 기능이라고 볼 수도 있다. 비슷한 것으로는 SWR의
dedupingInterval
이 있는데, SWR은 이 dedupingInterval
시간동안 어느 컴포넌트에서 몇 번을 호출해도 저장되어있는 캐시에서 값을 불러오고, 다시 요청을 보내지 않는다.한번의 렌더링 과정이라는 주기가 이미 정해져있기 때문에, 별도의 revalidate는 없다.
주의할 점으로 Memoization은 Next.js에서 재구현한 fetch에서 제공되기에 다른 라이브러리를 사용하면 적용이 되지 않으며, GET method 요청에서만 작동한다.
Request Memoization 막기
또는 Request Memoization는 각 path마다 다르게 적용되는데, 이때 query string이 달라져도 다른 경로로 인식한다. 이를 이용해 무의미한 구분용 query string을 추가하는 방식을 사용할 수도 있다.
fetch('https://blog.wibaek.net?meta=1') // 위와 아래의 요청은 서로 달리 memoization 된다 fetch('https://blog.wibaek.net?meta=2')
Data Cache
Data Cache는 fetch별로 데이터 캐싱을 할 수 있다. 이때 Data Cache는 서버에서 진행되기 때문에 모든 사용자가 같은 캐시된 데이터를 확인하게 된다.
그렇기 때문에 유저별로 다른 응답이 들어오는 API(내 정보 가져오기 API 등)에 대해서 주의해야하는데, 문제가 생기는것을 막기 위해 Next.js는 기본적으로 쿠키나 세션이 포함된 요청에 대해서는
Revalidate
Time-based Revalidation
Time-based Revalidation는 정해진 시간마다 캐싱된 데이터를 갱신하는 방식으로, stale-while-revalidate와 유사한 전략을 취하고 있다.
fetch('https://blog.wibaek.net/1', { next: { revalidate: 3600 } })
- 처음으로 온 fetch 요청은 캐싱되어 있지 않기에 Data Source에서 데이터를 가져오고, Data Cache에 데이터를 저장한다.
next.revalidate
로 지정한 시간내에 다시 온 요청에 대해서는 Data Cache에 저장된 데이터를 반환한다.
next.revalidate
로 지정한 시간이 지난후 온 요청에 대해서도 여전히 Data Cache에 저장된 데이터를 반환하나, 데이터 revalidate를 시도한다.- 데이터 revalidate 시 background에서 새롭게 Data Source에서 데이터를 가져와 Data Cache에 저장한다. 이때 revalidate 실패시에는 기존 데이터가 유지된다.
- 성공적으로 새로운 데이터를 가져온 이후로는, 요청시에 새로운 데이터를 반환한다.
이때 Request Memoization는 Data Cache의 앞단에서 작동하기 때문에, 데이터 revalidate가 되는 시점에 여러 요청을 날렸다고 해도, 모두 같은(기존에 캐싱된) 응답이 돌아오기 때문에 데이터 정합성 훼손을 걱정하지 않아도 된다.
On-demand Revalidation
Data Cache 막기
let data = await fetch('https://blog.wibaek.net/1', { cache: 'no-store' })
요청이 캐싱되는 것을 막기 위해서는
{ cache: 'no-store' })
옵션을 fetch 시 붙여준다.Full Route Cache
Client-side Router Cache
위의 캐싱들은 모두 서버에서 적용되는 반면, 클라이언트에서 적용되는 Router Cache가 존재한다.