
Next.js를 학습하면서 헷갈렸던 개념에 대해 정리하고자한다.
먼저, SSR/SSG/ISR 페이지라는 구분이다.
특히 SSR 페이지 라는 표현은 실제 동작 방식과 다른 인상을 주기 때문에 오해가 자주 생긴다.
다음으로, Page Router와 App Router 모두 SSR과 Hydration 차이점이다.
Page Router와 App Router 모두 SSR과 Hydration이 발생할 수 있지만, 그 범위와 처리 방식은 다르다.
먼저 SSR/SSG/ISR이 왜 혼동을 유발하는지 정리하고,
이어서 Page Router와 App Router의 SSR/Hydration 범위와 처리 방식 차이를 비교해 보겠다.
과거 Next.js에서는 페이지를 다음과 같이 구분했다.
하지만 이 구분은 렌더링 방식의 차이라기보다 캐싱 전략의 차이에 가까웠다.
SSG/ISR/SSR 모두 서버에서 HTML을 만들 수 있다.
SSG/ISR도 서버에서 HTML을 생성하지만, SSR처럼 매 요청마다 생성하는 게 아니라 빌드 시(또는 재검증 시) 생성한 결과를 캐시/재사용한다.
| 구분 | 언제 HTML을 만드느냐 | 얼마나 오래 캐시하느냐 |
|---|---|---|
| SSG | 빌드 시 1회 | 영구 |
| ISR | 빌드 시 + 일정 주기 | 재검증 |
| SSR | 요청 시 매번 | 캐시 없음 |
그런데 이름이 “SSR 페이지”이다 보니
“SSR만 서버에서 렌더링하고, SSG/ISR은 다른 방식이다”라고 오해하기 쉽다.
하지만 실제론 SSG/ISR도 서버에서 HTML을 만든다.
다만 SSG/ISR은 ‘한 번 만들어 둔 결과를 재사용’하는 쪽이고, SSR은 ‘요청마다 다시 만든다’는 쪽이다.
그래서 App Router에서는 이 혼동을 줄이기 위해 용어를 이렇게 정리했다.
| App Router 용어 | 의미 |
|---|---|
| Dynamic Page | 요청마다 새로 렌더링되는 페이지 |
| Static Page | 캐시(full route cache)된 HTML을 사용하는 페이지 (SSG/ISR) |
App Router에서는 “SSR/SSG/ISR” 대신
“Dynamic / Static”이라는 캐싱 관점의 용어로 정리했다.
Page Router와 App Router 모두 서버에서 HTML을 생성(SSR)한다는 점은 동일하다.
하지만 두 방식은 SSR 책임 분리 구조와 hydration 처리 방식에서 근본적인 차이가 있다.
Page Router는 Server / Client 컴포넌트 구분이 없다.
즉, 모든 컴포넌트는 서버에서도 실행될 수 있고, 클라이언트에서도 다시 실행될 수 있다.
서버에서 하는 일
getServerSideProps, getStaticProps 실행__NEXT_DATA__에 직렬화클라이언트에서 하는 일
__NEXT_DATA__를 통해 서버 데이터 복원브라우저에 전달되는 구조
특징
Hydration 특징
Page Router는
서버가 만든 HTML 위에, 클라이언트가 같은 페이지 트리를 다시 실행해 이벤트를 붙이며 ‘페이지 전체’를 한 번에 hydration 한다.
Page Router 전체 처리 과정
1) 요청/빌드 트리거
2) 서버에서 실행
3) 브라우저로 전달되는 구성
4) 클라이언트에서 Hydration
App Router는 Server Component와 Client Component가 구조적으로 분리됩니다.
서버에서 하는 일
클라이언트에서 하는 일
브라우저에 전달되는 구조
특징
Hydration 특징
App Router는
서버 컴포넌트는 서버에서만 실행되고 결과(RSC/HTML)만 전달되며, 상호작용이 필요한 ‘클라이언트 컴포넌트’만 부분적으로 hydration 된다.
App Router 전체 처리 과정 (RSC 기반)
1) 요청/캐시 판단
요청이 들어오면 Next.js가 이 라우트가 Static으로 재사용 가능한지 / Dynamic으로 매번 새로 그려야 하는지를 판단한다.
2) 서버에서 실행 (Server Component)
3) 브라우저로 전달되는 구성
4) 클라이언트에서 복원 + 부분 Hydration
5) 스트리밍 & Suspense (가능해지는 이유)
용어의 재정의 (SSR/SSG/ISR → Dynamic/Static)
Page Router App Router SSR 차이
| 구분 | Page Router | App Router |
|---|---|---|
| 렌더링 단위 | 페이지 (Page) | 컴포넌트 (Server / Client) |
| Hydration | 전체 (Full) 페이지 로드 후 전체 JS 실행 | 부분 (Partial) Client Component만 실행 |
| JS 번들 크기 | 큼 (모든 컴포넌트 코드 포함) | 작음 (Client Component 코드만 포함) |
| 데이터 전송 | NEXT_DATA (JSON) | RSC Payload (직렬화된 트리) |
| 주요 특징 | 설정이 단순하나 최적화 한계 존재 | "Streaming, Suspense 등 정교한 제어 가능" |