Full Route Cache는 한 마디로 ‘페이지 자체를 캐싱하는 것’이라 할 수 있다.
Next 서버 측에서 빌드 타임에 특정 페이지의 렌더링 결과를 캐싱하는 기능이다. 빌드 시에 Request Memoization와 Data Cache를 거쳐 반환된 특정 경로에 대한 페이지를 Full Route Cache로 저장하는 것이다. 이후 같은 경로의 페이지에 접속 요청이 생기면, Full Route Cache가 HIT 되어 캐시된 페이지를 브라우저에 반환한다(Pages Router의 SSG 방식의 렌더링과 유사하게 동작한다고 할 수 있다). 이를 통해, 요청이 오면 캐시된 결과를 즉시 반환하여 응답 속도를 크게 높일 수 있다.
Full Route Cache는 Static Page에만 적용된다. 이때, Static Page는 기본적으로 Dynamic Page가 아닌 경우의 페이지에 해당한다.
async function ServerComponent() {
const response = await fetch("..."); // 또는 no-store 옵션 있는 경우
return <div>...</div>;
}import { cookies } from "next/headers";
async function ServerComponent() {
const cookieStore = cookies();
const theme = cookieStore.get("theme");
return <div>...</div>;
}async function Page({ searchParams }: { searchParams: { q: string }}) {
const q = searchParams.q;
return <div>...</div>;
}| 동적 함수 (쿠키,헤더,쿼리스트링) | 데이터 캐시 | 페이지 분류 |
|---|---|---|
| YES | NO | Dynamic Page |
| YES | YES | Dynamic Page |
| NO | NO | Dynamic Page |
| NO | YES | Static Page |
결론적으로, Full Route Cache를 적용할 수 있는 Static Page로 페이지를 구성하는 것이 권장된다. 물론, Dynamic Page를 사용해야 하는 경우에도 Request Memoization, Data Cache는 유효하므로 각각 경우에 맞게 최적화할 수 있다.
아래의 예시의 경우, 쿼리 스트링을 가져와서 사용자와 동적으로 상호작용해야 하므로, 해당 컴포넌트에서는 Static Page로 만들 수 없으며 Full Route Cache를 적용할 수 없다. 따라서 Data Cache를 적용하는 것이 최선이다.
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ q?: string }>;
}) {
const resolvedSearchParams = await searchParams;
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/search?q=${resolvedSearchParams.q}`,
{ cache: "force-cache" }
);
if (!response.ok) {
return <div>에러가 발생했습니다.</div>;
}
const books: BookData[] = await response.json();
return (
<div>
{books.map((book) => (
<BookItem key={book.id} {...book} />
))}
</div>
);
}Full Route Cache를 무효화하는 방법은 두 가지가 있다.
generateStaticParams쿼리 파라미터를 갖는 상세 페이지의 경우, 동적으로 경로를 가져와야 하지만 Next가 제공하는 generateStaticParams 함수를 통해 지정한 쿼리 파라미터의 값을 가지는 페이지를 빌드 타임에 미리 생성할 수 있다. 따라서 이 함수는 Pages Router의 getStaticPaths 와 유사한 기능을 하는 함수라 할 수 있다.
export function generateStaticParams() {
return [{ id: "1" }, { id: "2" }, { id: "3" }]; // 값은 문자열로 지정해야 함
}
export default async function Page({
params,
}: {
params: Promise<{ id?: string }>;
}) {
const resolvedParams = await params;
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/${resolvedParams.id}`
);
if (!response.ok) {
return <div>에러가 발생했습니다.</div>;
}
return (<></>);
}
Next.js는 generateStaticParams 에 지정하지 않은 페이지에 대해서도 실시간으로 캐싱을 진행한다. 특정 상세 페이지 재접속 시 네트워크 응답 속도가 108ms->21ms 로 감소한 것을 확인할 수 있다.

dynamicParams만약, generateStaticParams 에 명시하지 않은 페이지의 경우 모두 NotFound 페이지로 보내고 싶을 수도 있다. 이러한 경우에는 dynamicParams 의 값을 false 로 지정하면 된다.
export const dynamicParams = false;
export function generateStaticParams() {
return [{ id: "1" }, { id: "2" }, { id: "3" }];
}
페이지의 유형을 강제할 수 있다. 페이지 상단에 export const dynamic = "옵션명" 형식으로 사용 가능하다.
| 옵션명 | 설명 |
|---|---|
| auto | 최초 요청에 대해 서버에서 새로 생성, 이후 요청에 대해 캐시된 페이지를 사용 |
| force-dynamic | 페이지를 강제로 Dynamic Page로 설정 |
| force-static | 페이지를 강제로 Static Page로 설정 |
| error | 페이지를 강제로 Static Page로 설정 (설정하면 안되는 이유를 빌드 오류로 표시) 에러 발생 시 캐시된 페이지를 사용 |
브라우저에 저장되는 캐시로, 페이지 이동을 효율적으로 진행하기 위해 페이지의 일부 데이터를 보관한다. 페이지 이동 시 공통적으로 사용되는 레이아웃 컴포넌트 등의 RSC Payload 데이터를 캐시한다. 이를 통해 페이지 전환 시 불필요한 데이터 요청 없이 캐시된 레이아웃을 재사용하여 빠르게 화면을 구성할 수 있다.
참고자료
한 입 크기로 잘라먹는 Next.js (이정환)