캐싱
생성일: 2024-03-25
수정일: 2024-03-25
Next.js는 렌더링 작업과 데이터 요청을 캐싱함으로써 애플리케이션의 성능을 향상시키고 비용을 절감한다. 이 페이지에서는 Next.js 캐싱 메커니즘, 구성할 수 있는 API, 그리고 이들이 서로 어떻게 상호작용하는지에 대해 심층적으로 살펴본다.
Tip
이 페이지는 Next.js가 내부적으로 어떻게 작동하는지 이해하는 데 도움이 되지만, Next.js를 생산적으로 사용하기 위해 필수적인 지식은 아니다. Next.js의 대부분 캐싱 휴리스틱은 API 사용 방식에 따라 결정되며, 복잡한 구성 없이 또는 최소한의 구성으로 최고 성능을 낼 수 있는 기본값이 제공된다.
개요
다음은 다양한 캐싱 메커니즘과 그 목적에 대한 개괄적인 개요다:
매커니즘 | 무엇을 | 어디서 | 목적 | 지속 시간 |
---|---|---|---|---|
요청 메모이제이션 | 함수의 리턴 값 | 서버 | 컴포넌트 트리에서 데이터 재사용 | 개별 요청 라이프사이클 |
데이터 캐시 | 데이터 | 서버 | 사용자 요청 및 배포 전반에 걸쳐 데이터 저장 | 영구(재검증 가능) |
전체 라우트 캐시 | HTML과 RSC payload | 서버 | 렌더링 비용 절감 및 성능 향상 | 영구(재검증 가능) |
라우터 캐시 | RSC payload | 클라이언트 | 탐색 시 서버 요청 감소 | 사용자 세션 또는 시간 기반 |
기본적으로 Next.js는 성능 향상과 비용 절감을 위해 가능한 한 많은 것을 캐싱한다. 이는 라우트가 정적 렌더링 되고 데이터 요청이 캐싱 된다는 것을 의미한다. 단, 이를 원하지 않는 경우에는 옵트아웃할 수 있다. 아래 다이어그램은 기본 캐싱 동작을 보여준다. 빌드 시 라우트가 정적으로 렌더링되는 시점과 정적 라우트를 처음 방문했을 때의 시점이다.
캐싱 동작은 라우트가 정적 또는 동적으로 렌더링되는지, 데이터가 캐싱되는지 아닌지, 그리고 요청이 초기 방문인지 이후 탐색인지에 따라 달라진다. 사용 사례에 따라 개별 라우트와 데이터 요청에 대한 캐싱 동작을 구성할 수 있다.
요청 메모이제이션(Request Memoization)
React는 fetch
API를 확장하여 동일한 URL과 옵션을 가진 요청을 자동으로 메모이제이션 한다. 이는 React 컴포넌트 트리의 여러 곳에서 동일한 데이터에 대해 fetch 함수를 호출하더라도 한 번만 실행된다는 것을 의미한다.
예를 들어, 라우트 전체에서 동일한 데이터를 사용해야 하는 경우(예: 레이아웃, 페이지 및 다수 컴포넌트에서) 트리 상단에서 데이터를 fetch하고 컴포넌트 간에 프로퍼티를 전달할 필요가 없다. 대신, 네트워크를 통해 동일한 데이터를 여러 번 요청할 때 성능을 걱정할 필요 없이 필요한 컴포넌트에서 데이터를 fetch 할 수 있다.
// app/example.tsx
async function getItem() {
// `fetch` 함수는 자동으로 캐시된다.
const res = await fetch('https://.../item/1');
return res.json();
}
// 이 함수는 두 번 호출되지만 처음 한 번만 실행된다.
const item = await getItem(); // cache MISS
// 두 번째 호출은 라우트의 어느 곳에서나 가능하다.
const item = await getItem(); // cache HIT
요청 메모이제이션 작동 방식
- 라우트 렌더링 중에 특정 요청이 처음 호출되면 결과가 메모리에 없으므로 캐시
MISS
가 발생한다. - 따라서 함수가 실행되고 데이터가 외부 소스에서 fetch 되며, 그 결과가 메모리에 저장된다.
- 동일한 렌더링 패스에서 해당 요청에 대한 후속 함수 호출은 캐시
HIT
가 되며, 함수를 실행하지 않고 메모리에서 데이터가 반환된다. - 라우트가 렌더링되고 렌더 패스가 완료되면 메모리가 "리셋"되고 모든 요청 메모이제이션 항목이 지워진다.
렌더 패스(render pass)
렌더 패스란 React에서 컴포넌트 트리를 렌더링하는 한 주기를 말한다.
React에서 상태가 변경되거나 prop이 변경되면 영향을 받는 컴포넌트와 그 하위 컴포넌트들이 리렌더링된다. 이 리렌더링 과정이 렌더 패스다.
렌더 패스는 다음과 같은 단계로 진행된다:
- React는 변경된 상태나 prop을 기반으로 가상 DOM 트리를 생성한다.
- React는 이전 렌더링의 가상 DOM 트리와 새로운 가상 DOM 트리를 비교한다.
- React는 실제 DOM에 필요한 변경 사항만 적용한다.
하나의 렌더 패스 동안 React는 요청 메모이제이션을 사용하여 동일한 데이터에 대한 중복 요청을 방지한다. 렌더 패스가 완료되면 메모이제이션된 데이터는 더 이상 필요하지 않으므로 메모리에서 제거된다.
따라서 "렌더 패스" 동안에만 요청 메모이제이션의 이점을 얻을 수 있고, 그 이후에는 데이터 캐시를 사용해야 한다.
Note
Next.js에서 페이지 렌더링은 두 단계로 진행된다.
- 서버 렌더링 단계
- 클라이언트 렌더링(하이드레이션) 단계
요청 메모이제이션은 이 두 단계에서 모두 일시적으로 작동한다.
- 서버 렌더링 단계
- 이 단계에서 요청 메모이제이션이 적용되어 중복 요청이 방지된다.
- 하지만 렌더링이 완료되면 메모리가 리셋되고 메모이제이션 항목이 제거된다.
- 클라이언트 렌더링 단계
- 클라이언트에서 렌더링할 때도 요청 메모이제이션이 일시적으로 적용된다.
- 렌더링 완료 후에는 다시 메모리가 리셋되고 메모이제이션 항목이 제거된다.
이렇게 메모리를 재설정하는 이유는 렌더링 주기가 완료된 후에는 더 이상 메모이제이션된 데이터가 필요하지 않기 때문이다. 다음 렌더링 주기에서는 새로운 메모이제이션 항목이 생성된다.
이를 통해 Next.js는 한 렌더링 주기 내에서만 요청 메모이제이션의 이점을 취하고, 메모리 누수 등의 부작용을 방지한다.
Tip
- 요청 메모이제이션은 Next.js 기능이 아닌 React 기능이다. 여기에서 소개하는 이유는 다른 캐싱 메커니즘과의 상호작용을 보여주기 위함이다.
- 메모이제이션은
fetch
요청의GET
메서드에만 적용된다. - 메모이제이션은 React 컴포넌트 트리에만 적용된다. 이는 다음을 의미한다:
generateMetadata
,generateStaticParams
, 레이아웃, 페이지 및 기타 서버 컴포넌트에서의fetch
요청에 적용된다.- 라우트 핸들러에서의
fetch
요청에는 적용되지 않는다. 라우트 핸들러는 React 컴포넌트 트리의 일부가 아니기 때문이다.
fetch
가 적합하지 않은 경우(예: 일부 데이터베이스 클라이언트, CMS 클라이언트 또는 GraphQL 클라이언트)에는 Reactcache
함수를 사용하여 함수를 메모이제이션할 수 있다.
지속 시간
캐시는 React 컴포넌트 트리의 렌더링이 완료될 때까지 서버 요청 수명 주기 동안 지속된다.
재검증
메모이제이션은 서버 요청 간에 공유되지 않고 렌더링 중에만 적용되므로 재검증할 필요가 없다.
옵트아웃
메모이제이션은 fetch
요청의 GET
메서드에만 적용되며, POST
, DELETE
등 다른 메서드는 메모이제이션되지 않는다. 이는 React의 기본 동작이며, 이를 옵트아웃하는 것은 권장되지 않는다.
개별 요청을 관리하려면 AbortController
의 signal
프로퍼티를 사용할 수 있다. 그러나 이는 요청을 메모이제이션에서 옵트아웃하는 것이 아니라, 진행 중인 요청을 중단시킨다.
// app/example.js;
const { signal } = new AbortController();
fetch(url, { signal });
데이터 캐시(Data Cache)
Next.js에는 데이터 fetch 결과를 유지하는 데이터 캐시(Data Cache)가 내장되어 있다. 이는 Next.js가 네이티브 fetch API를 확장하여 서버의 각 요청이 자체적인 영구 캐싱 시맨틱을 설정할 수 있도록 하기 때문에 가능하다.
Tip
브라우저에서 fetch
의 cache
옵션은 요청이 브라우저의 HTTP 캐시와 어떻게 상호작용할지를 나타내지만, Next.js에서 cache
옵션은 서버 측 요청이 서버의 데이터 캐시와 어떻게 상호작용할지를 나타낸다.
기본적으로 fetch
를 사용하는 데이터 요청은 캐시된다. fetch
의 cache
와 next.revalidate
옵션을 사용하여 캐싱 동작을 구성할 수 있다.
데이터 캐시 작동 방식
- 렌더링 중에
fetch
요청이 처음 호출되면 Next.js는 데이터 캐시에서 캐시된 응답을 확인한다. - 캐시된 응답이 있으면 즉시 반환되고 메모이제이션된다.
- 캐시된 응답이 없으면 데이터 소스에 요청이 이루어지고, 결과가 데이터 캐시에 저장되며 메모이제이션된다.
- 캐시되지 않은 데이터(예:
{ cache: 'no-store' }
)의 경우 항상 데이터 소스에서 결과를 가져오고 메모이제이션된다. - 데이터가 캐시되었든 아니든 요청은 항상 메모이제이션되어 React 렌더 패스 동안 동일한 데이터에 대한 중복 요청을 방지한다.
데이터 캐시와 요청 메모이제이션의 차이점
두 캐싱 메커니즘 모두 캐시된 데이터를 재사용하여 성능을 향상시키는 데 도움이 되지만, 데이터 캐시는 수신된 요청과 배포 전반에 걸쳐 지속되는 반면 메모이제이션은 요청 수명 주기 동안만 지속된다.
- 메모이제이션을 통해 렌더링 서버에서 데이터 캐시 서버(예: CDN 또는 Edge 네트워크) 또는 데이터 소스(예: 데이터베이스 또는 CMS)로 네트워크 경계를 가로지르는 동일한 렌더 패스 내의 중복 요청 수를 줄인다.
- 데이터 캐시를 통해서는 원본 데이터 소스로 전송되는 요청 수를 줄인다.
요청 메모이제이션과 데이터 캐시의 주요 차이점 요약 정리
요청 메모이제이션:
- React 렌더링 단계에서만 발생하는 일시적인 캐싱
- 동일한 렌더 패스 내에서 중복 데이터 요청을 방지하는 역할
- 메모리에 임시로 저장되며 렌더링이 완료되면 제거됨
- 주로 렌더링 성능 최적화에 목적이 있음
데이터 캐시:
- 서버 수준에서 지속적으로 유지되는 캐싱
- 여러 요청/배포 간에 데이터 캐시를 재사용하여 원본 데이터 소스로의 요청 수 감소
- 캐시 제어 옵션(cache, revalidate 등)을 통해 캐싱 동작 구성 가능
- 서버의 부하 감소 및 응답 시간 단축에 목적이 있음
요약하면, 요청 메모이제이션은 단일 렌더링 주기 내 성능 향상을, 데이터 캐시는 전반적인 서버 부하 감소와 응답 시간 단축을 목적으로 한다. 두 메커니즘이 서로 다른 계층에서 작동하여 Next.js 애플리케이션의 전체 성능을 향상시킨다.
지속 시간
재검증하거나 옵트아웃하지 않는 한, 데이터 캐시는 수요청 및 배포 전반에 걸쳐 지속된다.
재검증
캐시된 데이터는 두 가지 방식으로 재검증할 수 있다:
- 시간 기반 재검증: 일정 시간이 지난 후 새 요청이 있을 때 데이터를 재검증한다. 자주 변경되지 않고 최신 상태가 덜 중요한 데이터에 유용한다.
- 온디맨드 재검증: 이벤트(예: 폼 제출) 기반으로 데이터를 재검증한다. 온디맨드 재검증은 태그 기반 또는 경로 기반 방식을 사용하여 한 번에 데이터 그룹을 재검증할 수 있다. 최신 데이터를 가능한 한 빨리 표시하려는 경우(예: 헤드리스 CMS의 콘텐츠가 업데이트될 때) 유용하다.
시간 기반 재검증
리소스의 캐시 수명(초 단위)을 설정하기 위해 fetch
의 next.revalidate
옵션을 사용하여 일정 간격으로 데이터를 재검증할 수 있다.
// 최대 매시간마다 재검증
fetch('https://...', { next: { revalidate: 3600 } });
또는 Route Segment Config 옵션을 사용하여 세그먼트 내의 모든 fetch
요청을 구성하거나 fetch
를 사용할 수 없는 경우에 대해 구성할 수 있다.
시간 기반 재검증 작동 방식
revalidate
를 포함한 fetch 요청이 처음 호출되면 데이터를 외부 데이터 소스에서 가져와 데이터 캐시에 저장한다.- 지정된 시간(예: 60초) 내에 호출되는 요청은 캐시된 데이터를 반환한다.
- 시간이 지난 후 다음 요청에서도 캐시된(지연된) 데이터가 반환된다.
- Next.js는 백그라운드에서 데이터 재검증을 트리거한다.
- 데이터를 성공적으로 가져오면 Next.js가 데이터 캐시에 데이터를 업데이트한다.
- 백그라운드 재검증이 실패하면 이전 데이터가 그대로 유지된다.
이는 stale-while-revalidate 동작과 유사하다.
온디맨드 재검증
데이터는 경로(revalidatePath
)나 캐시 태그(revalidateTag
)를 통해 온디맨드로 재검증할 수 있다.
온디맨드 재검증 작동 방식
fetch
요청이 처음 호출되면 데이터를 외부 데이터 소스에서 가져와 데이터 캐시에 저장한다.- 온디맨드 재검증이 트리거되면 해당 캐시 항목이 캐시에서 제거된다.
- 이는 새 데이터를 fetch할 때까지 지연된 데이터를 캐시에 유지하는 시간 기반 재검증과 다르다.
- 다음에 요청이 들어오면 다시 캐시
미스
가 발생하고, 데이터를 외부 데이터 소스에서 가져와 데이터 캐시에 저장한다.
옵트아웃
개별 데이터 fetch에 대해 cache
옵션을 no-store
로 설정하여 캐싱에서 옵트아웃할 수 있다. 이렇게 하면 fetch
가 호출될 때마다 데이터를 fetch한다.
// 개별 `fetch` 요청에 대해 캐싱 옵트아웃
fetch(`https://...`, { cache: 'no-store' });
또는 Route Segment Config 옵션을 사용하여 특정 라우트 세그먼트에 대한 캐싱을 옵트아웃할 수 있다. 이는 라우트 세그먼트 내의 모든 데이터 요청(타사 라이브러리 포함)에 영향을 미친다.
// 라우트 세그먼트 내 모든 데이터 요청에 대해 캐싱 옵트아웃
export const dynamic = 'force-dynamic';
전체 라우트 캐시(Full Route Cache)
관련 용어
자동 정적 최적화, 정적 사이트 생성 또는 정적 렌더링이라는 용어가 빌드 시 애플리케이션의 라우트를 렌더링하고 캐싱하는 프로세스를 지칭하는 데 혼용되어 사용되는 것을 볼 수 있습니다.
Next.js는 빌드 시에 자동으로 라우트를 렌더링하고 캐싱한다. 이는 매 요청마다 서버에서 렌더링하는 대신 캐시된 라우트를 제공할 수 있게 해주는 최적화다. 결과적으로 페이지 로드 속도가 빨라진다.
전체 라우트 캐시가 어떻게 작동하는지 이해하려면 React가 렌더링을 처리하는 방식과 Next.js가 그 결과를 캐싱하는 방식을 살펴보는 것이 도움이 된다.
1. 서버에서의 React 렌더링
서버에서 Next.js는 React의 API를 사용하여 렌더링을 조정한다. 렌더링 작업은 개별 라우트 세그먼트와 Suspense 경계에 따라 청크로 나뉘어진다.
각 청크는 두 단계로 렌더링된다:
- React는 서버 컴포넌트를 React 서버 컴포넌트 페이로드라고 하는 스트리밍에 최적화된 특수 데이터 형식으로 렌더링한다.
- Next.js는 React 서버 컴포넌트 페이로드와 클라이언트 컴포넌트 JavaScript 지침을 사용하여 서버에서 HTML을 렌더링한다.
즉, 작업을 캐싱하거나 응답을 전송하기 전에 모든 렌더링이 완료될 때까지 기다릴 필요가 없다. 대신 작업이 완료되는 즉시 응답을 스트리밍할 수 있다.
자세한 내용은 서버 컴포넌트 문서 참조
2. 서버에서의 Next.js 캐싱 (전체 라우트 캐시)
Next.js의 기본 동작은 서버에서 라우트의 렌더링 결과(React 서버 컴포넌트 페이로드 및 HTML)를 캐싱하는 것이다. 이는 빌드 시 또는 재검증 중에 정적으로 렌더링된 라우트에 적용된다.
3. 클라이언트에서의 React 하이드레이션 및 재조정
요청 시 클라이언트에서는 다음과 같은 일이 발생합니다:
- HTML을 사용하여 클라이언트 및 서버 컴포넌트의 빠른 비대화형 초기 미리보기를 즉시 표시한다.
- React 서버 컴포넌트 페이로드를 사용하여 클라이언트 및 렌더링된 서버 컴포넌트 트리를 재조정하고 DOM을 업데이트한다.
- JavaScript 지침을 사용하여 클라이언트 컴포넌트를 하이드레이션하고 애플리케이션을 대화형으로 만든다.
4. 클라이언트에서의 Next.js 캐싱 (라우터 캐시)
React 서버 컴포넌트 페이로드는 클라이언트 측 라우터 캐시(개별 라우트 세그먼트로 분할된 별도의 인메모리 캐시)에 저장된다. 이 라우터 캐시는 이전에 방문한 라우트를 저장하고 향후 라우트를 prefetch하여 탐색 경험을 개선하는 데 사용된다.
5. 후속 탐색
후속 탐색 또는 prefetch 중에 Next.js는 React 서버 컴포넌트 페이로드가 라우터 캐시에 저장되어 있는지 확인한다. 그렇다면 서버에 새 요청을 보내는 것을 건너뛴다.
라우트 세그먼트가 캐시에 없으면 Next.js는 서버에서 React 서버 컴포넌트 페이로드를 가져와 클라이언트의 라우터 캐시에 채운다.
정적 렌더링과 동적 렌더링
빌드 시 라우트가 캐시되는지 여부는 정적으로 렌더링되는지 동적으로 렌더링되는지에 따라 달라진다. 정적 라우트는 기본적으로 캐시되지만, 동적 라우트는 요청 시 렌더링되며 캐시되지 않는다.
아래 다이어그램은 캐시된 데이터와 캐시되지 않은 데이터에 대해 정적으로 렌더링된 라우트와 동적으로 렌더링된 라우트의 차이점을 보여준다:
정적 렌더링과 동적 렌더링에 대해 자세히 알아보기
지속 시간
기본적으로 전체 라우트 캐시는 지속된다. 즉, 렌더링 출력이 사용자 요청에 걸쳐 캐시된다.
무효화
전체 라우트 캐시를 무효화할 수 있는 두 가지 방법이 있다:
- 데이터 재검증: 데이터 캐시를 재검증하면 서버에서 컴포넌트를 다시 렌더링하고 새 렌더링 출력을 캐싱하여 라우터 캐시가 무효화된다.
- 재배포: 데이터 캐시와 달리 전체 라우트 캐시는 새 배포 시 지워진다.
옵트아웃
다음과 같은 방법으로 전체 라우트 캐시에서 옵트아웃 즉 들어오는 요청마다 컴포넌트를 동적으로 렌더링할 수 있다:
- 동적 함수 사용: 이렇게 하면 라우트가 전체 라우트 캐시에서 옵트아웃되고 요청 시 동적으로 렌더링된다. 데이터 캐시는 계속 사용할 수 있다.
dynamic = 'force-dynamic'
또는revalidate = 0
라우트 세그먼트 구성 옵션 사용: 이렇게 하면 전체 라우트 캐시와 데이터 캐시를 모두 건너뛴다. 즉, 서버로 수신되는 모든 요청에 대해 컴포넌트가 렌더링되고 데이터를 fetch한다. 라우터 캐시는 클라이언트 측 캐시이므로 계속 적용된다.- 데이터 캐시 옵트아웃: 라우트에 캐시되지 않는
fetch
요청이 있으면 이 라우트는 전체 라우트 캐시에서 옵트아웃된다. 특정fetch
요청의 데이터는 요청마다 fetch를 수행 한다. 캐싱에서 옵트아웃하지 않는 다른fetch
요청은 여전히 데이터 캐시에 캐시된다. 이를 통해 캐시된 데이터와 캐시되지 않은 데이터를 혼합할 수 있다.
라우터 캐시(Router Cache)
Next.js에는 사용자 세션이 진행되는 동안 개별 라우트 세그먼트별로 분할된 React Server Component Payload를 저장하는 인메모리 클라이언트 사이드 캐시가 있다. 이를 라우터 캐시(Router Cache)라고 한다.
Router Cache의 동작 방식
사용자가 라우트 간에 이동할 때 Next.js는 방문한 라우트 세그먼트를 캐시하고 사용자가 이동할 가능성이 있는 라우트를 prefetch한다(<Link>
컴포넌트가 뷰포트에 있는 경우).
이로 인해 사용자의 탐색 경험이 개선된다:
- 방문한 라우트가 캐시되어 즉시 뒤로/앞으로 탐색할 수 있으며, prefetch 와 부분 렌더링으로 인해 새로운 라우트로 빠르게 이동할 수 있다.
- 탐색 간에 전체 페이지 새로고침이 없으며 React 상태와 브라우저 상태가 유지된다.
라우터 캐시와 전체 라우트 캐시의 차이점
라우터 캐시는 사용자 세션 동안 브라우저에 React Server Component Payload를 임시로 저장하는 반면, 전체 라우트 캐시는 여러 사용자 요청에 걸쳐 서버에 React Server Component Payload와 HTML을 지속적으로 저장한다.
전체 라우트 캐시는 정적으로 렌더링된 라우트만 캐시하는 반면, Router Cache는 정적 및 동적으로 렌더링된 라우트 모두에 적용된다.
지속 시간
캐시는 브라우저의 임시 메모리에 저장된다. 라우터 캐시가 지속되는 시간은 두 가지 요인에 의해 결정된다:
- 세션: 캐시는 네비케이션에 걸쳐 유지된다. 그러나 페이지 새로고침 시 지워진다.
- 자동 무효화 기간: 개별 세그먼트의 캐시는 특정 시간 후에 자동으로 무효화된다. 기간은 라우트가 정적으로 렌더링되는지 동적으로 렌더링되는지에 따라 다르다:
- 동적 렌더링: 30초
- 정적 렌더링: 5분
페이지 새로고침은 모든 캐시된 세그먼트를 지우지만, 자동 무효화 기간은 마지막으로 액세스되거나 생성된 시점부터 개별 세그먼트에만 영향을 미친다.
prefetch={true}
를 추가하거나 동적으로 렌더링된 라우트에 대해 router.prefetch
를 호출하면 5분 동안 캐싱할 수 있다.
무효화
라우터 캐시를 무효화하는 방법에는 두 가지가 있다:
- Server Action에서:
- 경로로 (
revalidatePath
) 또는 캐시 태그로 (revalidateTag
) 요청 시 데이터를 다시 검증한다. cookies.set
이나cookies.delete
를 사용하면 쿠키를 사용하는 라우트가 오래되는 것을 방지하기 위해 라우터 캐시가 무효화된다(예: 인증).
- 경로로 (
router.refresh
를 호출하면 Router Cache가 무효화되고 현재 라우트에 대해 서버에 새 요청을 보낸다.
옵트아웃
라우터 캐시를 옵트아웃하는 것은 불가능하다. 그러나 router.refresh
, revalidatePath
또는 revalidateTag
를 호출하여 무효화할 수 있다(위 참조). 이렇게 하면 캐시가 지워지고 서버에 새 요청을 보내 최신 데이터가 표시되도록 한다.
또한 <Link>
컴포넌트의 prefetch
속성을 false
로 설정하여 prefetch를 옵트아웃할 수 있다. 그러나 이는 탭 바나 뒤로/앞으로 탐색과 같은 중첩된 세그먼트 간의 즉시 탐색을 허용하기 위해 30초 동안 라우트 세그먼트를 임시로 저장한다. 방문한 경로는 여전히 캐시된다.
캐시 상호 작용
다양한 캐싱 메커니즘을 구성할 때는 이들이 서로 어떻게 상호 작용하는지 이해하는 것이 중요다:
데이터 캐시와 전체 라우트 캐시
- 데이터 캐시를 재검증하거나 옵트아웃하면 렌더링 결과가 데이터에 의존하므로 전체 라우트 캐시가 무효화된다.
- 전체 라우트 캐시를 무효화하거나 옵트아웃해도 데이터 캐시에는 영향을 주지 않는다. 캐시된 데이터와 캐시되지 않은 데이터가 모두 있는 라우트를 동적으로 렌더링할 수 있다. 이는 페이지의 대부분이 캐시된 데이터를 사용하지만 요청 시점에 fetch해야 하는 데이터에 의존하는 몇 가지 컴포넌트가 있는 경우에 유용하다. 모든 데이터를 다시 fetch할 때의 성능 영향에 대해 걱정하지 않고도 동적으로 렌더링할 수 있다.
데이터 캐시와 클라이언트 사이드 라우터 캐시
- 라우트 핸들러에서 데이터 캐시를 재검증해도 라우트 핸들러는 특정 라우트에 연결되어 있지 않으므로 라우터 캐시가 즉시 무효화되지 않는다. 즉, 하드 리프레시가 발생하거나 자동 무효화 기간이 경과할 때까지 라우터 캐시는 이전 페이로드를 계속 제공한다.
- 데이터 캐시와 라우터 캐시를 즉시 무효화하려면 서버 액션에서
revalidatePath
또는revalidateTag
를 사용할 수 있다.