들어가며
React 18부터 도입된 Server Components는 렌더링 패러다임을 크게 바꾸고 있습니다. 이 글에서는 Server Components가 무엇인지, 왜 필요한지, 그리고 실제로 어떻게 활용하는지 살펴봅니다.
Server Components란?
기존 렌더링의 문제점
기존의 React 렌더링에서는 모든 컴포넌트가 클라이언트에서 실행됩니다. 이는 몇 가지 문제를 낳습니다.
- 번들 크기: 서버에서만 필요한 라이브러리도 클라이언트 번들에 포함됩니다.
- 데이터 페칭 워터폴: 컴포넌트가 마운트된 후에야 데이터를 가져올 수 있습니다.
- 보안: 민감한 로직이 클라이언트에 노출될 수 있습니다.
동작 원리
Server Components는 서버에서만 실행되고, 클라이언트로는 직렬화된 React 트리(RSC Payload)만 전송됩니다. 덕분에 클라이언트 번들에서 완전히 제외됩니다.
Server Components는 HTML을 반환하는 게 아닙니다. React의 직렬화된 컴포넌트 트리를 반환합니다. 이게 SSR과의 핵심 차이입니다.
실전 활용법
데이터 페칭
Server Components에서는 `async/await`를 컴포넌트 함수에 직접 사용할 수 있습니다.
```tsx async function PostList() { const posts = await db.query('SELECT * FROM posts ORDER BY created_at DESC'); return ( <ul> {posts.map((p) => ( <li key={p.id}>{p.title}</li> ))} </ul> ); } ```
컴포넌트 분리 전략
서버/클라이언트 경계를 잘 설계하는 것이 중요합니다. 상태나 이벤트 핸들러가 필요한 부분만 `"use client"`로 분리하세요.
상위 컴포넌트를 서버로 유지하면서 인터랙티브한 부분만 클라이언트로 내리는 패턴이 가장 효율적입니다.
성능 비교
실제 프로젝트에서 Server Components 도입 후 변화를 측정했습니다.
| 지표 | 도입 전 | 도입 후 |
|---|---|---|
| JS 번들 크기 | 420KB | 180KB |
| FCP | 1.8s | 0.9s |
| LCP | 2.4s | 1.1s |
번들 크기가 절반 이하로 줄고, 사용자가 첫 콘텐츠를 보는 시간도 크게 단축됐습니다.

주의사항
Server Components에는 몇 가지 중요한 제약이 있습니다.
- `useState`, `useEffect` 등 React Hooks 사용 불가
- `window`, `document` 등 브라우저 API 접근 불가
- 이벤트 핸들러(`onClick`, `onChange` 등) 사용 불가
- Context Provider를 직접 렌더링할 수 없음
이 중 하나라도 필요하다면 해당 컴포넌트에 `"use client"`를 선언해야 합니다.
마치며zzzz
Server Components는 처음엔 생소할 수 있지만, Next.js App Router에서 기본값이 된 만큼 꼭 이해하고 넘어가야 합니다. 렌더링 경계를 의식하면서 설계하는 습관을 들이면, 성능과 개발 경험 모두 크게 향상됩니다.
