Next는 렌더링 작업과 데이터 fetch 작업을 캐싱하여 어플리케이션의 성능을 개선합니다. 이번에는 Next의 캐싱 메커니즘과 캐싱을 설정하는 API에 대해서 알아보겠습니다.
주의사항
Next를 이해하는 데에 도움이 되지만 Next를 사용하기 위한 필수 지식은 아닙니다. 대부분의 캐싱 작업은 API를 어떻게 사용하는지에 따라서 결정되고 기본 설정 값으로도 좋은 성능을 낼 수 있습니다.
요청 memoization
: 서버 사이드에서 함수의 return 값을 캐싱합니다. 한 번의 페이지 요청에 대한 처리 과정에서 사용할 수 있으며 여러 컴포넌트에서 데이터를 재사용할 수 있습니다.
Data Cache
: 요청 memoization이 없을 때 서버 사이드에서 fetch api를 호출하게 되고 이에 따라 받은 응답을 캐싱합니다. 여러 사용자 사이에서 공유할 수 있는 데이터입니다.
Full route cache
: 서버 사이드에서 html과 RSC payload를 저장합니다.
Router Cache
: 클라이언트 사이드에서 RSC payload를 캐싱하여 네비게이션으로 인한 라우트 이동 시 서버 요청을 줄일 수 있습니다.
React에서 fetch API 사용 시 자동으로 요청을 memoize합니다. URL과 옵션이 같은 요청인 경우 여러 번 요청하는 것이 아니라 memoize한 결과 값을 반환해줍니다. 주의사항으로 GET 메써드를 사용한 요청에만 적용됩니다.
memoization을 사용하지 않으려면 fetch의 파라미터로 AbortController의 signal을 넘겨줄 수 있습니다.
Next는 서버로 들어오는 요청의 결과 데이터를 Data Cache에 저장합니다. 기본적으로 fetch를 사용하는 데이터 요청은 캐싱됩니다. 캐싱 동작을 설정하려면 fetch의 옵션으로 cache와 next.revalidate를 조정할 수 있습니다.
사용하지 않으려면
fetch(`https://...`, { cache: 'no-store' })
fetch 옵션으로 캐싱을 사용하지 않겠다고 명시하거나
export const dynamic = 'force-dynamic'
Route Segment Config Option을 사용하여 해당 route 세그먼트 내의 모든 fetch 요청을 캐싱하지 않겠다고 명시할 수 있습니다.
빌드 타임에 정적으로 렌더링된 route의 경우 RSC Payload와 html을 캐싱해둡니다.
Data Cache가 갱신되면 Router Cache도 갱신하게 됩니다. 또한 서버 배포를 다시 한 경우 초기화됩니다.
클라이언트 사이드 메모리에 개별 route 세그먼트 단위로 RSC payload를 캐싱해둡니다. Next는 방문했던 route 세그먼트를 캐싱하고, 뷰포트 내에 있는 Link 컴포넌트의 route를 prefetch합니다. Router Cache는 정적/동적 렌더링에 상관없이 적용됩니다.
만약 웹훅과 같이 써드 파티 이벤트의 결과로 Router Handler에서 데이터를 갱신하는 경우 Router Handler는 특정 route에 종속되어 있지 않기 때문에 revalidateTag를 사용하는 대신 revalidatePath로 경로를 명시해서 캐시를 갱신할 수 있습니다.