Page Router vs App Router vs React Server Components

Page Router vs App Router vs React Server Components

D
dongAuthor
6 min read

React 생태계가 진화함에 따라 Next.js는 개발자들에게 다양한 렌더링 옵션을 제공하고 있습니다. 특히 NextJS의 Page Router SSR(Server Side Rendering)과 React Server Components(RSC)가 있죠. 이번 글에서는 전통적인 Next.js Page Router 기반의 SSR과 Next.js App Router 기반의 SSR, 그리고 React Server Components의 차이점을 살펴봅시다.


NextJS App Router Server Component = React Server Component?

NextJs Docs 중 NextJS Server Components는 React 기반이라는 설명

결론부터 말씀드리면 NextJS App Router의 Server Component는 React의 Server Component를 기반으로 만들어졌습니다. React 팀이 설계한 Server Component의 핵심 아이디어를 Next.js가 받아들여, App Router를 통해 이에 맞는 생태계를 빠르게 구현한 것입니다.

다만, Page Router의 SSR은 조금 다릅니다. React Server Component가 나오기 이전에 먼저 NextJS에서 React와 SSR을 함께 사용할 수 있도록 하기 위한 독자적인 기술이기 때문입니다. 🤔

자 일단 Page Router를 한 번 보도록 합시다 !


Next.js Page Router 기반의 SSR

Next.js Page Router에서 SSR은 getServerSideProps라는 메서드를 사용하여 구현됩니다. 이 메서드는 페이지 요청 시 서버에서 데이터를 가져오는 역할을 합니다. 이를 통해 사용자는 요청 시점에 최신 데이터를 기반으로 렌더링된 HTML을 받을 수 있으며, 이는 SEO 최적화와 동적 데이터 처리가 중요한 프로젝트에서 유용합니다.

Page Router에서의 SSR의 주된 특징은 페이지 단위의 데이터 요청과 처리입니다. 이는 각각의 페이지가 독립적으로 데이터를 가져오고 렌더링하도록 설계되어 있어, 구성과 데이터 요청 로직이 명확하게 분리됩니다. 그러나 모든 페이지 요청마다 서버에서 전처리를 수행하기 때문에 트래픽이 많은 애플리케이션에서는 서버 부하가 증가할 수 있는 단점이 있습니다.

예제를 통해 살펴보면, 아래는 getServerSideProps를 이용한 기본적인 SSR 구현입니다:

export async function getServerSideProps(context) {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();

  return {
    props: { data },
  };
}

export default function Page({ data }) {
  return <div>{data.title}</div>;
}

위의 코드에서 데이터를 페이지 로드 시 서버에서 가져오며, 이 데이터는 클라이언트에 HTML로 보내집니다. 이처럼 Page Router 기반의 SSR은 명확한 데이터 흐름과 SEO 친화적 아키텍처를 제공합니다.


Next.js App Router와 React Server Components

NextJS Server Component 예시 사진

Next.js 13에서 App Router가 도입되며 React Server Components(RSC)를 기본으로 사용하는 구성이 가능해졌습니다. RSC는 클라이언트와 서버 간의 경계를 더 효과적으로 설정하여 애플리케이션의 성능 최적화를 목표로 합니다. App Router 기반의 SSR은 기존 Page Router보다 더 세부적이고 컴포넌트 중심적인 접근 방식을 제공합니다.

App Router는 데이터 요청과 렌더링의 유연성을 제공하며, 특정 컴포넌트를 서버에서 렌더링하고 나머지는 클라이언트에서 처리할 수 있습니다. 이러한 방식을 통해 초기 로드 시간을 줄이면서도 서버의 계산 부하를 효율적으로 분산할 수 있습니다. RSC는 React의 철학인 선언적 UI와 서버 중심 렌더링을 결합하여 개발자들이 클라이언트와 서버의 성능을 극대화할 수 있도록 합니다.

RSC의 주요 장점은 다음과 같습니다:

  • 컴포넌트 단위의 데이터 페칭: 필요한 데이터만 서버에서 가져오므로 트래픽 비용이 감소합니다.
  • 클라이언트의 번들 크기 감소: 불필요한 클라이언트 자바스크립트를 제거합니다.
  • 유연한 상태 관리: 클라이언트와 서버 간 상태를 효율적으로 공유할 수 있습니다.

다음 섹션에서는 App Router와 RSC를 사용하는 코딩 패턴과 고려해야 할 실무적인 이슈들을 알아보겠습니다.


Next.js Page Router 기반 SSR vs App Router 기반 SSR

Next.js는 Page Router(기존 방식)와 App Router(React Server Components 기반)라는 두 가지 핵심 라우팅 방식을 제공합니다. 두 방식 모두 SSR을 지원하지만, 작동 방식과 철학은 완전히 다릅니다.

1. Page Router 기반 SSR

Page Router는 Next.js의 전통적인 라우팅 방식으로, 주로 getServerSideProps를 통해 서버 사이드 렌더링을 지원합니다. 이 방식은 React 컴포넌트를 서버에서 HTML로 렌더링한 뒤, 클라이언트로 전송하고 하이드레이션 과정을 통해 인터랙션을 활성화합니다.

특징과 작동 원리

  • 데이터 페칭: getServerSideProps를 사용해 서버에서 데이터를 미리 가져옵니다.
  • HTML 렌더링: React 컴포넌트를 서버에서 HTML 문자열로 변환합니다.
  • 하이드레이션: 클라이언트에서 JavaScript가 이벤트 핸들러와 상태를 활성화합니다.
  • SEO 친화적: 검색 엔진 크롤러가 HTML 콘텐츠를 즉시 접근 가능하게 합니다.
// Page Router 기반 SSR 예시
export async function getServerSideProps() {
  const data = await fetch('https://api.example.com/data');
  return {
    props: { data },
  };
}

export default function Page({ data }) {
  return <div>{data.title}</div>;
}

한계점

  • 번들 크기 증가: 모든 JavaScript가 클라이언트로 전송되기 때문에 초기 로딩 속도가 느려질 수 있음.
  • 복잡한 데이터 흐름: 데이터 페칭 로직이 컴포넌트 외부에 위치하여 가독성이 떨어질 수 있음.

2. App Router 기반 SSR (React Server Components 활용)

Next.js 13부터 도입된 App Router는 React Server Components를 중심으로 설계되어 완전히 다른 SSR 접근 방식을 제공합니다. App Router 기반의 SSR은 React Server Components(RSC)를 활용해 서버에서만 실행되는 컴포넌트와 클라이언트에서 실행되는 컴포넌트를 효율적으로 분리합니다.

특징과 작동 원리

  • React Server Components 활용: 서버에서만 실행되는 컴포넌트를 HTML 대신 RSC Payload라는 직렬화된 데이터로 렌더링합니다.
  • 클라이언트 경계: 'use client'를 사용해 클라이언트 컴포넌트를 명시적으로 선언합니다.
  • 번들 크기 최적화: 서버 전용 로직은 클라이언트로 전송되지 않으므로 JavaScript 번들이 작아집니다.
  • 점진적 스트리밍: 서버에서 렌더링된 콘텐츠를 청크 단위로 스트리밍해 초기 로딩 속도를 개선합니다.
// App Router 기반 SSR 예시
// app/page.js (Server Component)
export default async function Page() {
  const data = await fetch('https://api.example.com/data');
  return <div>{data.title}</div>;
}

// components/Button.js (Client Component)
'use client';

export default function Button() {
  return <button>Click Me</button>;
}

이점

  • 성능 최적화: 서버 전용 컴포넌트를 통해 클라이언트의 JavaScript 로드를 최소화.
  • 데이터 페칭 단순화: 컴포넌트 자체에서 데이터를 직접 페칭.
  • 점진적 렌더링: 데이터가 도착하는 대로 콘텐츠를 렌더링해 사용자 경험 향상.

한계점

  • 학습 곡선: 기존 Page Router 방식에 익숙한 개발자들에게는 새로운 패러다임.
  • 제한된 클라이언트 상태 관리: 서버 컴포넌트 내에서는 상태 관리 훅(useState, useEffect) 사용 불가.

React Server Components (RSC)

React Server Components는 React 18에서 도입된 새로운 개념으로, Next.js App Router의 핵심 기반이 됩니다. RSC는 서버에서만 실행되는 컴포넌트를 정의하고, 클라이언트로는 해당 컴포넌트의 결과 데이터를 직렬화된 형태로 전송합니다.

RSC의 특징

  1. 서버 전용 실행: 컴포넌트가 서버에서만 렌더링되고 클라이언트로는 전송되지 않음.
  2. 상태 없음: 상태 관리 훅 사용 불가, 순수 렌더링 로직에 집중.
  3. 직접 데이터 페칭: 데이터베이스, 파일 시스템 등의 리소스에 직접 접근 가능.
// React Server Component 예시
async function Post({ id }) {
  const post = await fetch(`https://api.example.com/posts/${id}`);
  return <div>{post.title}</div>;
}

RSC의 강점

  • 번들 크기 감소: 서버 전용 코드가 클라이언트 번들에서 제외.
  • 데이터 접근 단순화: 별도의 API 계층 없이 데이터 소스에 직접 접근 가능.
  • 스트리밍 지원: 대규모 페이지를 점진적으로 렌더링 가능.

사견 및 마무리

Next.js가 2025년에도 여전히 웹 풀스택 프레임워크 1위를 유지하고 있는 이유는 바로 이러한 기술 혁신에 대한 민첩성과 실용성 때문이라고 생각됩니다. 빠르게 변화하는 IT 트렌드에 발맞춘 지속적인 업데이트, 실무 중심의 기능 제공, 그리고 개발 생산성을 극대화하는 철학이 결합되어 많은 개발자들이 믿고 선택하는 프레임워크로 자리 잡았다고 생각되네요 !