서버 컴포넌트
React 서버 컴포넌트를 사용하면 서버에서 렌더링되고 선택적으로 캐시될 수 있는 UI를 작성할 수 있습니다. Next.js에서는 렌더링 작업이 경로 세그먼트별로 더 세분화되어 스트리밍과 부분 렌더링이 가능하며, 세 가지 다른 서버 렌더링 전략이 있습니다:
이 페이지에서는 서버 컴포넌트의 작동 방식, 사용 시기 및 다양한 서버 렌더링 전략에 대해 설명합니다.
서버 렌더링의 이점
서버에서 렌더링 작업을 수행하는 데는 몇 가지 이점이 있습니다:
- 데이터 페칭: 서버 컴포넌트를 사용하면 데이터 페칭을 데이터 소스와 더 가까운 서버로 이동할 수 있습니다. 이는 렌더링에 필요한 데이터를 가져오는 데 걸리는 시간과 클라이언트가 수행해야 하는 요청 수를 줄여 성능을 향상시킬 수 있습니다.
- 보안: 서버 컴포넌트를 사용하면 토큰과 API 키와 같은 민감한 데이터와 로직을 클라이언트에 노출할 위험 없이 서버에 유지할 수 있습니다.
- 캐싱: 서버에서 렌더링함으로써 결과를 캐시하고 후속 요청과 사용자 간에 재사용할 수 있습니다. 이는 각 요청에서 수행되는 렌더링과 데이터 페칭의 양을 줄여 성능을 향상시키고 비용을 절감할 수 있습니다.
- 성능: 서버 컴포넌트는 기준선에서 성능을 최적화하기 위한 추가 도구를 제공합니다. 예를 들어, 전체가 클라이언트 컴포넌트로 구성된 앱으로 시작한 경우, UI의 상호작용이 없는 부분을 서버 컴포넌트로 이동하면 필요한 클라이언트 측 JavaScript의 양을 줄일 수 있습니다. 이는 인터넷 속도가 느리거나 성능이 낮은 기기를 사용하는 사용자에게 유용합니다. 브라우저가 다운로드, 구문 분석 및 실행해야 할 클라이언트 측 JavaScript가 줄어들기 때문입니다.
- 초기 페이지 로드 및 First Contentful Paint (FCP): 서버에서 HTML을 생성하여 사용자가 페이지를 렌더링하는 데 필요한 JavaScript를 클라이언트가 다운로드, 구문 분석 및 실행할 때까지 기다리지 않고 즉시 볼 수 있게 합니다.
- 검색 엔진 최적화 및 소셜 네트워크 공유 가능성: 렌더링된 HTML을 검색 엔진 봇이 페이지를 인덱싱하는 데 사용할 수 있으며, 소셜 네트워크 봇이 페이지의 소셜 카드 미리보기를 생성하는 데 사용할 수 있습니다.
- 스트리밍: 서버 컴포넌트를 사용하면 렌더링 작업을 청크로 분할하고 준비되는 대로 클라이언트에 스트리밍할 수 있습니다. 이를 통해 사용자는 전체 페이지가 서버에서 렌더링될 때까지 기다리지 않고도 페이지의 일부를 먼저 볼 수 있습니다.
Next.js에서 서버 컴포넌트 사용하기
기본적으로 Next.js는 서버 컴포넌트를 사용합니다. 이를 통해 추가 구성 없이 자동으로 서버 렌더링을 구현할 수 있으며, 필요한 경우 클라이언트 컴포넌트를 사용할 수 있습니다. 클라이언트 컴포넌트를 참조하세요.
서버 컴포넌트는 어떻게 렌더링되나요?
서버에서 Next.js는 React의 API를 사용하여 렌더링을 조율합니다. 렌더링 작업은 개별 경로 세그먼트와 Suspense 경계로 분할됩니다.
각 청크는 두 단계로 렌더링됩니다:
- React는 서버 컴포넌트를 React 서버 컴포넌트 페이로드(RSC 페이로드) 라고 하는 특별한 데이터 형식으로 렌더링합니다.
- Next.js는 RSC 페이로드와 클라이언트 컴포넌트 JavaScript 지침을 사용하여 서버에서 HTML을 렌더링합니다.
그런 다음 클라이언트에서:
- HTML은 경로의 빠른 비대화형 미리보기를 즉시 표시하는 데 사용됩니다. 이는 초기 페이지 로드에만 해당됩니다.
- React 서버 컴포넌트 페이로드는 클라이언트 및 서버 컴포넌트 트리를 조정하고 DOM을 업데이트하는 데 사용됩니다.
- JavaScript 지침은 클라이언트 컴포넌트를 하이드레이트하고 애플리케이션을 대화형으로 만드는 데 사용됩니다.
React 서버 컴포넌트 페이로드(RSC)란 무엇인가요?
RSC 페이로드는 렌더링된 React 서버 컴포넌트 트리의 간결한 바이너리 표현입니다. 클라이언트의 React에서 브라우저의 DOM을 업데이트하는 데 사용됩니다. RSC 페이로드에는 다음이 포함됩니다:
- 서버 컴포넌트의 렌더링 결과
- 클라이언트 컴포넌트가 렌더링되어야 할 위치에 대한 플레이스홀더와 해당 JavaScript 파일에 대한 참조
- 서버 컴포넌트에서 클라이언트 컴포넌트로 전달된 모든 props
서버 렌더링 전략
서버 렌더링에는 정적, 동적 및 스트리밍의 세 가지 하위 집합이 있습니다.
정적 렌더링 (기본값)
정적 렌더링을 사용하면 경로가 빌드 시에 렌더링되거나 데이터 재검증 후 백그라운드에서 렌더링됩니다. 결과는 캐시되어 콘텐츠 전송 네트워크(CDN)로 푸시될 수 있습니다. 이 최적화를 통해 사용자와 서버 요청 간에 렌더링 작업의 결과를 공유할 수 있습니다.
정적 렌더링은 경로에 사용자 개인화되지 않은 데이터가 있고 빌드 시 알 수 있는 경우에 유용합니다. 예를 들어 정적 블로그 게시물이나 제품 페이지가 있습니다.
동적 렌더링
동적 렌더링을 사용하면 경로가 각 사용자에 대해 요청 시에 렌더링됩니다.
동적 렌더링은 경로에 사용자에게 개인화된 데이터가 있거나 쿠키 또는 URL의 검색 매개변수와 같이 요청 시에만 알 수 있는 정보가 있는 경우에 유용합니다.
캐시된 데이터가 있는 동적 경로
대부분의 웹사이트에서 경로는 완전히 정적이거나 완전히 동적인 경우가 드뭅니다. 이는 연속적인 스펙트럼으로 볼 수 있습니다. 예를 들어, 주기적으로 재검증되는 캐시된 제품 데이터를 사용하지만 캐시되지 않은 개인화된 고객 데이터도 있는 전자 상거래 페이지가 있을 수 있습니다.
Next.js에서는 캐시된 데이터와 캐시되지 않은 데이터가 모두 있는 동적으로 렌더링되는 경로를 가질 수 있습니다. 이는 RSC 페이로드와 데이터가 별도로 캐시되기 때문입니다. 이를 통해 요청 시 모든 데이터를 가져오는 성능 영향에 대해 걱정하지 않고도 동적 렌더링을 선택할 수 있습니다.
동적 렌더링으로 전환
렌더링 중에 동적 함수나 캐시되지 않은 데이터 요청이 발견되면 Next.js는 전체 경로를 동적으로 렌더링하도록 전환합니다. 이 표는 동적 함수와 데이터 캐싱이 경로가 정적으로 렌더링되는지 또는 동적으로 렌더링되는지에 어떤 영향을 미치는지 요약합니다:
동적 함수 | 데이터 | 경로 |
---|---|---|
아니오 | 캐시됨 | 정적으로 렌더링됨 |
예 | 캐시됨 | 동적으로 렌더링됨 |
아니오 | 캐시되지 않음 | 동적으로 렌더링됨 |
예 | 캐시되지 않음 | 동적으로 렌더링됨 |
위 표에서 경로가 완전히 정적이려면 모든 데이터가 캐시되어야 합니다. 그러나 캐시된 데이터 페치와 캐시되지 않은 데이터 페치를 모두 사용하는 동적으로 렌더링된 경로를 가질 수 있습니다.
개발자로서 정적 렌더링과 동적 렌더링 중 하나를 선택할 필요가 없습니다. Next.js는 사용된 기능과 API를 기반으로 각 경로에 대한 최상의 렌더링 전략을 자동으로 선택합니다. 대신 특정 데이터를 캐시하거나 재검증할 시기를 선택하고, UI의 일부를 스트리밍하도록 선택할 수 있습니다.
동적 함수
동적 함수는 사용자의 쿠키, 현재 요청 헤더 또는 URL의 검색 매개변수와 같이 요청 시에만 알 수 있는 정보에 의존합니다. Next.js에서 이러한 동적 API는 다음과 같습니다:
이러한 함수 중 하나라도 사용하면 전체 경로가 요청 시 동적 렌더링으로 전환됩니다.
스트리밍

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

스트리밍은 기본적으로 Next.js App Router에 내장되어 있습니다. 이는 초기 페이지 로딩 성능을 개선할 뿐만 아니라 전체 경로 렌더링을 차단할 수 있는 더 느린 데이터 페치에 의존하는 UI도 개선합니다. 예를 들어 제품 페이지의 리뷰와 같은 경우입니다.
loading.js
를 사용하여 경로 세그먼트 스트리밍을 시작하고 React Suspense를 사용하여 UI 컴포넌트를 스트리밍할 수 있습니다. 자세한 정보는 로딩 UI 및 스트리밍 섹션을 참조하세요.