Next.js의 풀 라우트 캐시(Full Route Cache)는 빌드 타임에 특정 페이지를 미리 렌더링하여 캐싱하는 기능이다. 이는 요청 시 즉각적으로 페이지를 반환하여 빠른 응답 속도를 제공한다. Page Router의 SSG(정적 사이트 생성) 방식과 유사하지만, App Router의 새로운 데이터 처리 방식을 반영한 점에서 차별화된다.
풀 라우트 캐시는 빌드 타임에 페이지를 생성하고, 렌더링 결과를 Next.js 서버의 캐시에 저장한다.
이후 브라우저에서 해당 페이지 요청이 들어오면, 새롭게 페이지를 생성하지 않고 캐시된 페이지를 즉시 반환한다.
예를 들어 /a와 같은 주소를 갖는 페이지를 미리 렌더링.
페이지에 필요한 데이터는 리퀘스트 메모이제이션 또는 데이터 캐시를 거쳐 렌더링된 결과를 생성.
생성된 페이지는 풀 라우트 캐시에 저장.
브라우저가 /a 페이지 요청.
풀 라우트 캐시에서 해당 페이지를 찾아 HIT 시 즉시 반환.
새로운 렌더링 과정이 필요하지 않으므로, 빠른 속도로 페이지 응답.
이런 풀 라우트 캐시 동작 방식은, Page Router에서 빌드 타임에 페이지를 생성하고, 미리 저장해두었다가 요청 시 반환하는 SSG(정적 사이트 생성) 방식과 매우 유사하다. 그러니까 이 풀 라우트 캐시는 브라우저에 요청이 들어왔을 때 캐시에 저장된 페이지를 그대로 응답해주는 페이지 캐싱 기능이라고 생각하면 된다.
Next.js의 페이지는 크게 Static Page와 Dynamic Page로 나뉘는데 풀 라우트 캐시는 Static Page에만 적용된다.
| 동적함수 | 데이터 캐시 | 페이지 분류 |
|---|---|---|
| YES | NO | Dynamic Page |
| YES | YES | Dynamic Page |
| NO | NO | Dynamic Page |
| NO | YES | Static Page |
페이지 내부에서 cache: "no-store"로 설정된 fetch 요청.
데이터가 매번 새롭게 불러와지는 경우.
서버 컴포넌트만 해당된다. 클라이언트 컴포넌트는 페이지 유형에 영향을 미치지 않는다.
접속 요청에 따라서 언제든지 시간에 따라서 자유롭게 변화할 수 있는 쿠키, 헤더, 쿼리스트링과 같은 동적 값들을 꺼내 사용하는 경우.
요청마다 값이 변경될 가능성이 높아 정적 생성이 불가능.
Dynamic Page로 분류되지 않는 경우, 기본적으로 Static Page로 설정된다.
정적 데이터 캐싱이 가능하며, 풀 라우트 캐시를 통해 빠른 응답이 가능하다.
풀 라우트 캐시 적용
페이지가 빌드 타임에 미리 렌더링되어 풀 라우트 캐시에 저장된다.
서버 가동 후 요청이 들어오면 캐시에 저장된 페이지를 바로 반환 (HIT). 추가적인 렌더링이 필요 없으므로 빠른 응답 속도를 제공한다.
풀 라우트 캐시 미적용.
빌드 타임에 사전 렌더링이 진행되지 않음.
요청이 들어올 때마다 새로운 데이터를 가져와 페이지를 동적으로 생성. Static Page보다 느리지만, 동적 데이터에 유연하게 대응할 수 있다.
풀 라우트 캐시 사용이 가능한 Static Page를 사용하면 훨씬 더 빠른 페이지 응답이 가능하기 때문에 더 권장되는 방식이지만 그렇다고 해서 Dynamic Page 사용이 좋지 않은 방식이란 건 아니다.
Dynamic Page는 비효율적이거나 느리다고만 볼 수 없다. 다음과 같은 상황에서는 Dynamic Page를 필요로 한다.
또한, Dynamic Page는 풀 라우트 캐시는 적용되지 않지만, 리퀘스트 메모이제이션과 데이터 캐시는 동일하게 활용할 수 있다.
이를 통해 API 요청을 최적화하거나 데이터를 캐싱해 성능을 개선할 수 있다.
Static Page는 풀 라우트 캐시를 통해 빠른 응답 속도를 제공하기 때문에 가능한 한 적극적으로 활용하는 것이 좋다.
그러나 Dynamic Page도 필요에 따라 사용해야 한다.
예를 들어, 동적 값이나 실시간 데이터가 필수적인 경우 Dynamic Page가 더 적합하다.
Static Page와 Dynamic Page는 서로 보완적인 역할을 하며, 두 방식을 적절히 필요에 맞게 혼합해 사용하는 것이 중요하다.
풀 라우트 캐시는 정적 페이지에만 적용되지만, 정적 페이지도 특정 Revalidate 주기로 캐싱 데이터를 갱신할 수 있다.
만약 현재 페이지가 Static Page로 설정이 되어서 빌드 타임에 미리 생성이 되어 풀 라우트 캐시에 저장 되도록 설정이 되어있다 하더라도, 이 페이지를 구성하는 컴포넌트들 중에 fetch,revalidate:3이렇게 하나의 데이터 페칭 요청이라도 Revalidate옵션이 존재한다면 현재 설정된 Revalidate타임에 따라서 데이터 캐시 뿐만 아니라, 페이지 캐시 즉 풀 라우트 캐시 또한 함께 업데이트 된다.
이는 Page Router에서 사용되던 ISR(증분 정적 재생성) 방식과 동일하게 작동 한다.
캐시된 페이지를 HIT하여 반환.
Revalidate 주기가 만료되지 않은 경우, 캐시된 데이터 그대로 사용.
캐시 데이터와 페이지가 STALE(상태 만료) 상태로 표시. (데이터 캐시가 상하면 당연히 이 데이터를 이용해서 생성한 페이지 자체도 상해버리게 된다.)
요청 시 기존 캐시 데이터를 반환하며, 백그라운드에서 최신 데이터를 가져와 캐시와 페이지를 갱신. ( 데이터 캐시를 먼저 갱신 하고 그 다음에 페이지까지 다시 렌더링을 해서 풀 라우트 캐시의 값을 업데이트 시켜주면서 풀 라우트 캐시에 보관된 페이지를 최신화 시키게 된다.)
예를 들면
A라는 Static Page가 빌드 타임에 생성이 될 때 3s간격으로 Revalidate돼야 데이터 페칭이 존재하게 된다면 데이터 캐시에 보관이 되는 데이터 페칭의 결과 뿐만 아니라, 풀 라우트 캐시에 저장이 되는 페이지의 렌더링 결과 또한 revalidate 타임으로 설정된 3s주기로 계속해서 다시 업데이트 된다.
빌드 타임에 미리 생성된 페이지를 캐시에서 즉시 반환.
서버 부하를 줄이고, 사용자 경험(UX)을 향상.
데이터 캐시와 연동하여, 데이터를 효율적으로 재활용.
특정 Revalidate 주기로 데이터와 페이지를 동기화.
풀 라우트 캐시는 Next.js App Router에서 제공하는 강력한 정적 페이지 캐싱 기능이다.
정적 페이지의 경우, 빌드 타임에 페이지를 생성하여 캐시에 저장한 뒤 빠른 속도로 응답한다.
그러나 모든 페이지에 적용할 수는 없으며, Dynamic Page는 상황에 맞는 데이터 캐싱 전략과 함께 사용해야 한다.
자주 변경되지 않는 콘텐츠.
빠른 응답 속도가 요구되는 페이지.
동적 데이터가 필요하지 않은 페이지.