목차
서버컴포넌트의 이점
- 데이터 페칭: Server Components를 사용하면 데이터 소스에 더 가까운 서버에서 데이터 페칭을 수행할 수 있습니다. 이는 렌더링에 필요한 데이터를 가져오는 시간을 줄이고 클라이언트에서 요청해야 하는 횟수를 줄여 성능을 향상시킬 수 있습니다.
- 보안: Server Components를 사용하면 토큰이나 API 키와 같은 민감한 데이터와 로직을 클라이언트에 노출될 위험 없이 서버에 유지할 수 있습니다.
-> 만약 데이터 페칭 코드가 있다면 데이터를 받아 데이터를 씌어서 html를 항상 내려주기 때문에 로직이 js번들에 포함되지 않아
노출 위험이 없다. (use client를 써야 하는 컴포넌트는 무조건 js 번들에 포함되어 브라우저로 전달)
- 캐싱: 서버에서 렌더링함으로써 결과를 캐시하고 이후 요청과 사용자 간에 재사용할 수 있습니다. 이는 각 요청 시 수행되는 렌더링과 데이터 페칭의 양을 줄여 성능을 향상시키고 비용을 절감할 수 있습니다.
- 성능: Server Components는 성능을 최적화할 수 있는 추가 도구를 제공합니다. 예를 들어, 완전히 Client Components로 구성된 앱에서 비인터랙티브 UI 부분을 Server Components로 이동하면 클라이언트 측 JavaScript의 양을 줄일 수 있습니다. 이는 느린 인터넷 또는 성능이 낮은 장치를 사용하는 사용자에게 유리합니다.
- 초기 페이지 로드 및 First Contentful Paint (FCP)(opens in a new tab): 서버에서 HTML을 생성하여 사용자가 페이지를 즉시 볼 수 있게 하고, 클라이언트가 페이지를 렌더링하는 데 필요한 JavaScript를 다운로드, 파싱 및 실행할 필요가 없습니다.
- 검색 엔진 최적화 및 소셜 네트워크 공유 가능성: 렌더링된 HTML은 검색 엔진 봇이 페이지를 인덱싱하고 소셜 네트워크 봇이 페이지의 소셜 카드 미리보기를 생성하는 데 사용할 수 있습니다.
- 스트리밍: Server Components를 사용하면 렌더링 작업을 청크로 분할하고 준비되는 대로 클라이언트에 스트리밍할 수 있습니다. 이를 통해 전체 페이지가 서버에서 렌더링될 때까지 기다리지 않고도 사용자가 페이지의 일부를 먼저 볼 수 있습니다.
서버 컴포넌트가 랜더링 되는 과정
서버에서 Next.js는 React의 API를 사용하여 렌더링을 조정합니다. 렌더링 작업은 개별 경로 세그먼트와 Suspense Boundaries(opens in a new tab)에 따라 청크로 분할됩니다.
청크 렌더링 과정
1. react는 서버 컴포넌트를 react server component payload 라는 특별한 데이터 형식으로 렌더링합니다.
2. next.js는 rsc payload와 client component javascript 지침을 사용하여 서버에서 HTML을 렌더링합니다.
++추가 정보
client component javascript 지침은 브라우저에서 실행되는 코드를 넣고 직렬화 규칙을 위한 지침을 말한다.
클라이언트 렌더링 과정
1. HTML을 사용하여 경로의 빠른 비인터렉티브 미리보기를 즉시 표시합니다. (이는 초기 페이지 로드에만 해당됩니다.)
2. react server component payload를 사용하여 client와 server component 트리를 조장하고 dom을 업데이트합니다.
3. javascript 지침을 사용하여 client components를 하이드레이션하고 애플리케이션을 인터렉티브하게 만듭니다.
단계 설명
| 1. 서버 렌더링 | Server Components만 실행해서 React tree를 만듦 (HTML 아님) |
| 2. RSC Payload 생성 | React tree를 이진 청크(RSC payload)로 직렬화 |
| 3. 클라이언트로 스트리밍 | 브라우저는 점진적으로 payload 수신하고 html은 즉시 보여준다. |
| 4. React가 DOM 생성 | React는 payload를 바탕으로 초기 DOM 구성 (reconcile 단계) |
| 5. Client Component 발견 | 해당 위치에서 JS 번들 요청 |
| 6. Hydration | Client Component hydrate → 이벤트 핸들러 연결, 상호작용 준비 완료 |
++추가 정보
reconcile은 두개의 컴포넌트 트리인 서버 컴포넌트트리, 클라이언트 컴포넌트 트리가 있는 상태에서 rsc payload가 비어있는 곳을 client component로 채워넣는 과정을 뜻한다.


RSC(react sergver component payload)란?
RSC Payload는 렌더링된 React Server Components 트리의 간결한 이진 표현입니다. 이는 클라이언트에서 React가 브라우저의 DOM을 업데이트하는 데 사용됩니다. RSC Payload에는 다음이 포함됩니다:
- Server Components의 렌더링된 결과
- Client Components가 렌더링되어야 할 위치와 해당 JavaScript 파일에 대한 참조
- Server Component에서 Client Component로 전달된 모든 props
hydrate
브라우저의 렌더링 과정을 거친 이후 js 번들을 다운로드 받아 실행하여 기능만 입힘
-> 서버 컴포넌트를 사용함으로써 요청하는 자바스크립트 번들의 양을 줄일 수 있음

- HTML 수신 → DOM 트리 생성
- 서버에서 전달된 HTML 또는 클라이언트에서 React가 만든 HTML을 브라우저가 파싱해서 DOM 트리를 만듦
- CSS 수신 → CSSOM 트리 생성
- <link>나 <style>의 CSS를 파싱해서 CSSOM(CSS Object Model) 트리 생성
- DOM + CSSOM → 렌더 트리(Render Tree) 구성
- 실제 화면에 표시될 요소들을 기반으로 렌더 트리 생성
- display: none은 포함되지 않음
- 레이아웃(Layout) 계산
- 각 요소의 절대적인 위치(x, y), 크기(width, height) 등을 계산
- 페인트(Painting)
- 요소들의 픽셀 데이터를 생성해서 화면에 그리기
- 컴포지팅(Compositing)
- 레이어를 GPU 또는 브라우저 엔진이 합쳐서 화면에 최종 표시
- 자바스크립트 실행 (layout.js, main-app.js 등)
- hydration, 이벤트 등록, 동적 동작 추가
- React 앱의 실제 "행동"이 붙는 시점
server rendering stragies
Static Rendering (Default)
Static Rendering에서는 빌드 타임 또는 데이터 재검증 후 백그라운드에서 경로가 렌더링됩니다. 결과는 캐시되며 Content Delivery Network (CDN)(opens in a new tab)에 푸시될 수 있습니다. 이 최적화는 사용자와 서버 요청 간에 렌더링 작업의 결과를 공유할 수 있게 합니다.
Static Rendering은 사용자에게 개인화되지 않은 데이터가 있으며 빌드 타임에 알 수 있는 경로(예: 정적 블로그 게시물 또는 제품 페이지)에 유용합니다.
Dynamic Rendering
Dynamic Rendering에서는 경로가 요청 시 각 사용자에 대해 렌더링됩니다.
Dynamic Rendering은 사용자에게 개인화된 데이터가 있거나 요청 시에만 알 수 있는 정보(예: 쿠키 또는 URL의 검색 매개변수)가 있는 경로에 유용합니다.
캐시된 데이터가 있는 동적 경로
대부분의 웹사이트에서는 경로가 완전히 정적이거나 완전히 동적이지 않습니다 - 이는 스펙트럼입니다. 예를 들어, 일정 간격으로 재검증되는 캐시된 제품 데이터를 사용하는 전자 상거래 페이지와 개인화된 고객 데이터를 포함하는 경우가 있습니다.
Next.js에서는 캐시된 데이터와 캐시되지 않은 데이터를 모두 사용하는 동적으로 렌더링된 경로를 가질 수 있습니다. 이는 RSC Payload와 데이터가 별도로 캐시되기 때문에 가능합니다. 이를 통해 모든 데이터를 요청 시 가져오는 성능 영향을 걱정하지 않고 동적 렌더링을 선택할 수 있습니다.
예시: 전자상거래 페이지
// /products/[slug]/page.tsx
export default async function ProductPage({ params }) {
const product = await getProduct(params.slug); // 캐시 가능
const user = await getUserFromCookie(); // 캐시 불가
return (
<>
<ProductCard data={product} /> // 정적 가능
<PersonalizedSection user={user} /> // 동적만 가능
</>
);
}
ProductCard 같은 부분은 캐시된 RSC Payload만 재사용
PersonalizedSection 같은 부분만 요청마다 새로 렌더링
즉, 전체 페이지를 새로 그리는 게 아니라,
캐시 가능한 부분과 불가능한 부분을 나눠서 처리하는 것.
Dynamic Functions
동적 함수는 사용자의 쿠키, 현재 요청 헤더 또는 URL의 검색 매개변수와 같이 요청 시에만 알 수 있는 정보에 의존합니다. Next.js에서 이러한 동적 API는 다음과 같습니다:
- cookies()
- headers()
- unstable_noStore()
- unstable_after()
- searchParams prop
이 함수들 중 하나를 사용하면 전체 경로가 요청 시 동적으로 렌더링됩니다.
Streaming

스트리밍을 통해 서버에서 UI를 점진적으로 렌더링할 수 있습니다. 작업은 청크로 나누어지고 준비되는 대로 클라이언트에 스트리밍됩니다. 이를 통해 전체 콘텐츠가 렌더링될 때까지 기다리지 않고도 사용자가 페이지의 일부를 즉시 볼 수 있습니다.

트리밍은 Next.js App Router에 기본적으로 내장되어 있습니다. 이는 초기 페이지 로딩 성능을 향상시키고, 전체 경로를 렌더링하는 데 방해가 되는 느린 데이터 페칭에 의존하는 UI를 개선합니다. 예를 들어, 제품 페이지의 리뷰가 해당됩니다.
loading.js와 UI 컴포넌트를 React Suspense를 사용하여 경로 세그먼트 스트리밍을 시작할 수 있습니다.
'코딩 정보 > NextJs' 카테고리의 다른 글
| [개념부터 nextjs] next-auth 사용하기 (3) | 2025.08.14 |
|---|---|
| [개념부터 Nextjs] Redirecting (6) | 2025.08.09 |
| [개념부터 Nextjs] Linking and Navigating (3) | 2025.07.29 |
| [NextJs] 파이어 베이스를 통해 채팅을 구현해보자 (0) | 2025.05.12 |
| [NextJs] msw 세팅 제대로 하기 feat: 서버 컴포넌트 (2) | 2025.04.30 |