Next.js 렌더링 전략 및 서버 컴포넌트 비교
Next.js의 다양한 렌더링 전략과 서버 컴포넌트는 HTML 생성 시점과 보관 방식에서 차이가 있다. 서버 컴포넌트는 이들과는 다른 차원의 개념이지만, Next.js App Router에서 함께 작동하여 전체적인 렌더링 최적화를 목표로 한다.
1. 서버 사이드 렌더링 (SSR: Server-Side Rendering)
- 개념: 클라이언트(브라우저)에서 페이지를 요청할 때마다 서버에서 실시간으로 해당 페이지의 HTML을 생성하여 클라이언트에 전송하는 방식이다.
- 특징:
- 항상 최신 데이터를 보여준다.
- 사용자 요청 시마다 서버 부하가 발생한다.
- 초기 로딩 속도 및 SEO에 유리하다.
- HTML 생성 시점: 매 요청(request)마다 서버에서 동적으로 생성된다.
- HTML 보관:
- 생성된 HTML은 서버에 영구적으로 보관되지 않고, 클라이언트에게 응답으로 전송된 후 사라진다. (물론 서버의 메모리나 캐시에 일시적으로 존재할 수는 있다.)
- 각 요청에 대한 HTML은 독립적으로 생성되고 전달된다.
- Next.js 구현:
getServerSideProps
함수를 사용하는 페이지 (Pages Router) 또는 Next.js 13+ App Router에서 기본적으로 제공하는 동작 (데이터 페칭을 기다리는 async
서버 컴포넌트 등).
2. 정적 사이트 생성 (SSG: Static Site Generation)
- 개념: 웹 애플리케이션을 빌드(build)하는 시점에 모든 페이지의 HTML을 미리 생성하여 정적인 파일로 저장하고, 이를 CDN(Content Delivery Network)과 같은 곳에 배포하여 클라이언트에게 제공하는 방식이다.
- 특징:
- 빌드 시점에 데이터가 고정된다.
- 매우 빠른 페이지 로딩 속도와 낮은 서버 부하를 가진다.
- 데이터가 자주 변경되지 않는 블로그, 마케팅 페이지 등에 적합하다.
- HTML 생성 시점: 애플리케이션을
build
하는 시점 (배포 전)에 미리 생성된다.
- HTML 보관:
- 빌드 후 생성된 HTML 파일들은 웹 서버나 CDN에 정적인 파일 형태로 영구적으로 보관된다.
- 클라이언트 요청 시 서버는 이 미리 생성된 HTML 파일을 그대로 전달한다.
- Next.js 구현:
getStaticProps
함수를 사용하는 페이지 (Pages Router).
3. 증분 정적 재생성 (ISR: Incremental Static Regeneration)
- 개념: SSG의 장점(빠른 로딩, 낮은 부하)을 유지하면서도, 데이터가 변경되었을 때 전체 사이트를 다시 빌드할 필요 없이 특정 페이지를 주기적으로 또는 요청 시에 재생성할 수 있게 하는 SSG의 확장된 개념이다.
- 특징:
- SSG처럼 빠른 초기 로딩 속도를 제공한다.
- 데이터 변경에 유연하게 대응할 수 있다.
- Next.js Vercel 플랫폼에서 특히 효율적이다.
- HTML 생성 시점:
- 최초에는 빌드 시점에 HTML이 생성된다.
- 이후에는
revalidate
옵션에 설정된 주기(예: 60초)가 만료되고 새로운 요청이 들어왔을 때 백그라운드에서 HTML을 다시 생성한다. (이때 이전 버전의 HTML을 먼저 보여주고, 새로운 HTML 생성이 완료되면 다음 요청부터 새로운 HTML을 보여준다.)
- HTML 보관:
- 생성된 HTML 파일들은 웹 서버나 CDN에 보관된다.
revalidate
주기가 만료되어 페이지가 재생성되면, 기존의 HTML 파일은 새로운 HTML 파일로 교체된다.
- Next.js 구현:
getStaticProps
함수와 함께 revalidate
옵션을 사용하는 페이지 (Pages Router).
4. 서버 컴포넌트 (Server Components)
- 개념: React 컴포넌트의 코드가 서버에서만 실행되고 렌더링되며, 그 결과물(HTML, CSS 및 클라이언트 컴포넌트에 대한 참조)만 클라이언트로 스트리밍되는 새로운 패러다임의 컴포넌트이다. 클라이언트 JavaScript 번들에 포함되지 않는다.
- 특징:
- 클라이언트 번들 크기를 줄여 성능을 향상시킨다.
- 서버에서 직접 데이터베이스나 파일 시스템에 접근할 수 있다.
- 상호작용이 없는 UI(정적인 콘텐츠)에 적합하다.
- React 18과 Next.js 13 App Router의 핵심 기능이다.
- HTML 생성 시점: 주로 요청(request) 시점에 서버에서 렌더링된다. (SSR과 유사하게 실시간으로 동적인 HTML을 생성하는 데 사용될 수 있다.)
- 단, SSG/ISR처럼 빌드 시점에 미리 렌더링될 수도 있다. Next.js App Router의 라우트 세그먼트 렌더링 동작에 따라 SSG/ISR처럼 동작하게 구성할 수 있다.
- HTML 보관:
- 서버 컴포넌트가 렌더링한 HTML은 SSR과 유사하게 클라이언트에 전송된 후 영구적으로 보관되지 않는다. (서버에 일시적인 캐싱은 있을 수 있다.)
- 클라이언트는 HTML을 받은 후 이 HTML을 기반으로 UI를 구성하지만, 서버 컴포넌트의 JavaScript는 받지 않는다.
- Next.js 구현: Next.js 13+ App Router의 기본 동작 (파일 상단에
'use client'
지시자가 없는 컴포넌트).
요약 비교표
특성 | 서버 사이드 렌더링 (SSR) | 정적 사이트 생성 (SSG) | 증분 정적 재생성 (ISR) | 서버 컴포넌트 (Server Components) |
---|
HTML 생성 시점 | 매 요청 시 서버에서 | 빌드 시점 | 빌드 시점 + 재검증 주기 만료 시 | 주로 요청 시 서버에서 |
HTML 보관 장소 | 클라이언트에 전송 후 휘발성 | 웹 서버/CDN에 정적 파일로 영구 보관 | 웹 서버/CDN에 정적 파일로 영구 보관 | 클라이언트에 전송 후 휘발성 |
데이터 최신성 | 항상 최신 | 빌드 시점 데이터 | 주기적으로 최신화 가능 | 요청 시 최신 데이터 반영 |
클라이언트 JS 번들 | 전체 JS 번들 포함 (Hydration 필요) | 전체 JS 번들 포함 (Hydration 필요) | 전체 JS 번들 포함 (Hydration 필요) | 해당 컴포넌트 JS 제외 (Hydration 불필요) |
주요 장점 | 항상 최신 데이터, SEO | 매우 빠른 로딩, 낮은 서버 부하 | SSG+데이터 최신성, 효율적 재생성 | 번들 크기 감소, 직접 DB 접근, 성능 |
적합한 사용처 | 사용자마다 다른 데이터, 실시간 정보 | 블로그, 마케팅 페이지, Docs | 블로그, 뉴스, 상품 목록 (데이터 변화 잦은 SSG) | 상호작용 없는 UI, 데이터 페칭, 보안 |
핵심적인 차이:
- SSR, SSG, ISR은 HTML을 언제, 어디서 생성하고 누구에게 제공할 것인가에 대한 렌더링 전략이다. 이들은 클라이언트에서 React 애플리케이션을 Hydrate하여 상호작용 가능하게 만드는 것을 전제로 한다.
- 서버 컴포넌트는 어떤 React 컴포넌트의 코드를 서버에서 실행하고 어떤 컴포넌트의 코드를 클라이언트에서 실행할 것인가에 대한 컴포넌트 유형의 구분이다. 서버 컴포넌트는 클라이언트 번들에서 제외되어 Hydration 과정의 오버헤드를 줄이는 데 기여한다.
Next.js App Router에서는 이러한 개념들이 복합적으로 사용된다. 예를 들어, SSR 페이지 내부에 서버 컴포넌트가 포함될 수 있고, 정적으로 생성된 페이지(SSG/ISR) 내부에 서버 컴포넌트의 결과물이 포함될 수도 있다. 이는 Next.js가 렌더링 전략과 컴포넌트 실행 환경을 더욱 세밀하게 제어할 수 있도록 돕는다.