문서
App Router 사용하기
서버 컴포넌트

서버 컴포넌트

React 서버 컴포넌트를 사용하면 서버에서 렌더링되고 선택적으로 캐시될 수 있는 UI를 작성할 수 있습니다. Next.js에서는 렌더링 작업이 경로 세그먼트별로 더 세분화되어 스트리밍과 부분 렌더링이 가능하며, 세 가지 다른 서버 렌더링 전략이 있습니다:

이 페이지에서는 서버 컴포넌트의 작동 방식, 사용 시기 및 다양한 서버 렌더링 전략에 대해 설명합니다.

서버 렌더링의 이점

서버에서 렌더링 작업을 수행하는 데는 몇 가지 이점이 있습니다:

  • 데이터 페칭: 서버 컴포넌트를 사용하면 데이터 페칭을 데이터 소스와 더 가까운 서버로 이동할 수 있습니다. 이는 렌더링에 필요한 데이터를 가져오는 데 걸리는 시간과 클라이언트가 수행해야 하는 요청 수를 줄여 성능을 향상시킬 수 있습니다.
  • 보안: 서버 컴포넌트를 사용하면 토큰과 API 키와 같은 민감한 데이터와 로직을 클라이언트에 노출할 위험 없이 서버에 유지할 수 있습니다.
  • 캐싱: 서버에서 렌더링함으로써 결과를 캐시하고 후속 요청과 사용자 간에 재사용할 수 있습니다. 이는 각 요청에서 수행되는 렌더링과 데이터 페칭의 양을 줄여 성능을 향상시키고 비용을 절감할 수 있습니다.
  • 성능: 서버 컴포넌트는 기준선에서 성능을 최적화하기 위한 추가 도구를 제공합니다. 예를 들어, 전체가 클라이언트 컴포넌트로 구성된 앱으로 시작한 경우, UI의 상호작용이 없는 부분을 서버 컴포넌트로 이동하면 필요한 클라이언트 측 JavaScript의 양을 줄일 수 있습니다. 이는 인터넷 속도가 느리거나 성능이 낮은 기기를 사용하는 사용자에게 유용합니다. 브라우저가 다운로드, 구문 분석 및 실행해야 할 클라이언트 측 JavaScript가 줄어들기 때문입니다.
  • 초기 페이지 로드 및 First Contentful Paint (FCP): 서버에서 HTML을 생성하여 사용자가 페이지를 렌더링하는 데 필요한 JavaScript를 클라이언트가 다운로드, 구문 분석 및 실행할 때까지 기다리지 않고 즉시 볼 수 있게 합니다.
  • 검색 엔진 최적화 및 소셜 네트워크 공유 가능성: 렌더링된 HTML을 검색 엔진 봇이 페이지를 인덱싱하는 데 사용할 수 있으며, 소셜 네트워크 봇이 페이지의 소셜 카드 미리보기를 생성하는 데 사용할 수 있습니다.
  • 스트리밍: 서버 컴포넌트를 사용하면 렌더링 작업을 청크로 분할하고 준비되는 대로 클라이언트에 스트리밍할 수 있습니다. 이를 통해 사용자는 전체 페이지가 서버에서 렌더링될 때까지 기다리지 않고도 페이지의 일부를 먼저 볼 수 있습니다.

Next.js에서 서버 컴포넌트 사용하기

기본적으로 Next.js는 서버 컴포넌트를 사용합니다. 이를 통해 추가 구성 없이 자동으로 서버 렌더링을 구현할 수 있으며, 필요한 경우 클라이언트 컴포넌트를 사용할 수 있습니다. 클라이언트 컴포넌트를 참조하세요.

서버 컴포넌트는 어떻게 렌더링되나요?

서버에서 Next.js는 React의 API를 사용하여 렌더링을 조율합니다. 렌더링 작업은 개별 경로 세그먼트와 Suspense 경계로 분할됩니다.

각 청크는 두 단계로 렌더링됩니다:

  1. React는 서버 컴포넌트를 React 서버 컴포넌트 페이로드(RSC 페이로드) 라고 하는 특별한 데이터 형식으로 렌더링합니다.
  2. Next.js는 RSC 페이로드와 클라이언트 컴포넌트 JavaScript 지침을 사용하여 서버에서 HTML을 렌더링합니다.

그런 다음 클라이언트에서:

  1. HTML은 경로의 빠른 비대화형 미리보기를 즉시 표시하는 데 사용됩니다. 이는 초기 페이지 로드에만 해당됩니다.
  2. React 서버 컴포넌트 페이로드는 클라이언트 및 서버 컴포넌트 트리를 조정하고 DOM을 업데이트하는 데 사용됩니다.
  3. 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를 점진적으로 렌더링할 수 있습니다. 작업은 청크로 분할되어 준비되는 대로 클라이언트로 스트리밍됩니다. 이를 통해 사용자는 전체 콘텐츠가 렌더링을 마치기 전에 페이지의 일부를 즉시 볼 수 있습니다.

스트리밍되고 있는 청크에 대한 로딩 UI와 함께 클라이언트에서 부분적으로 렌더링된 페이지를 보여주는 다이어그램.

스트리밍은 기본적으로 Next.js App Router에 내장되어 있습니다. 이는 초기 페이지 로딩 성능을 개선할 뿐만 아니라 전체 경로 렌더링을 차단할 수 있는 더 느린 데이터 페치에 의존하는 UI도 개선합니다. 예를 들어 제품 페이지의 리뷰와 같은 경우입니다.

loading.js를 사용하여 경로 세그먼트 스트리밍을 시작하고 React Suspense를 사용하여 UI 컴포넌트를 스트리밍할 수 있습니다. 자세한 정보는 로딩 UI 및 스트리밍 섹션을 참조하세요.