ReactNextCentral

서버 컴포넌트

Published on
Next.js에서 데이터와 정적 렌더링 결과를 어떻게 캐싱하는지 알아보세요.
Table of Contents

리액트 서버 컴포넌트를 사용하면 서버에서 렌더링하고 선택적으로 캐싱할 수 있는 UI를 작성할 수 있습니다. Next.js에서는 스트리밍 및 부분 렌더링을 활성화하기 위해 라우트 세그먼트별로 렌더링 작업이 나뉩니다. 서버 렌더링 전략은 세 가지가 있습니다.

  1. 정적 렌더링
  2. 동적 렌더링
  3. 스트리밍

이 페이지에서는 서버 컴포넌트가 어떻게 작동하는지 언제 사용해야 하는지 그리고 다양한 서버 렌더링 전략에 대해 설명합니다.


서버 렌더링의 이점

서버에서 렌더링 작업을 수행함으로써 얻을 수 있는 여러 가지 이점이 있습니다.

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

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

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


서버 컴포넌트는 어떻게 렌더링됩니까?

서버에서 Next.js는 렌더링을 조정하기 위해 리액트의 API를 사용합니다. 렌더링 작업은 개별 라우트 세그먼트와 Suspense 경계별로 청크로 나뉩니다.

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

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

그런 다음 클라이언트에서 다음과 같이 동작합니다.

  1. HTML은 초기 페이지 로드만을 위해 빠른 비상호작용 미리보기를 즉시 표시하는 데 사용됩니다.
  2. 리액트 서버 컴포넌트 페이로드는 클라이언트 및 서버 컴포넌트 트리를 조정하고 DOM을 업데이트하는 데 사용됩니다.
  3. JavaScript 지침은 클라이언트 컴포넌트를 hydrate하고 애플리케이션을 상호작용 가능하게 만드는 데 사용됩니다.

서버 렌더링 전략

서버 렌더링에는 세 가지 하위 집합인 정적, 동적, 스트리밍이 있습니다.

정적 렌더링 (기본 설정)

정적 렌더링에서는 라우트가 빌드 시간에 렌더링되거나 데이터 재검증 후에 백그라운드에서 렌더링됩니다. 결과는 캐시되어 콘텐츠 전달 네트워크 (CDN)에 푸시될 수 있습니다. 이 최적화를 통해 렌더링 작업의 결과를 사용자와 서버 요청 간에 공유할 수 있습니다.

정적 렌더링은 라우트의 데이터가 사용자에게 특화되지 않고 빌드 시간에 알 수 있는 경우 유용합니다. 예를 들어 정적 블로그 게시물이나 제품 페이지와 같습니다.

동적 렌더링

동적 렌더링에서는 각 사용자에 대해 요청 시간에 라우트가 렌더링됩니다.

동적 렌더링은 라우트의 데이터가 사용자에게 특화되어 있거나 쿠키나 URL의 검색 매개변수와 같이 요청 시간에만 알 수 있는 정보를 가질 때 유용합니다.

동적 렌더링으로 전환하기

렌더링 중에 동적 함수 또는 캐시되지 않은 데이터 요청이 발견되면, Next.js는 전체 라우트를 동적으로 렌더링하게 됩니다. 아래 표는 동적 함수와 데이터 캐싱이 라우트가 정적 또는 동적으로 렌더링되는지에 어떻게 영향을 주는지 요약하고 있습니다.

동적 함수데이터라우트
없음캐시됨정적으로 렌더링됨
있음캐시됨동적으로 렌더링됨
없음캐시안됨동적으로 렌더링됨
있음캐시안됨동적으로 렌더링됨

위 표에서 라우트가 완전히 정적으로 렌더링되려면 모든 데이터가 캐시되어야 합니다. 그러나, 캐시된 데이터와 캐시되지 않은 데이터를 모두 사용하는 동적으로 렌더링된 라우트를 가질 수 있습니다.

개발자로서 정적 및 동적 렌더링 사이에서 선택할 필요가 없습니다. 왜냐하면 Next.js는 사용된 기능과 API를 기반으로 각 라우트에 대한 최적의 렌더링 전략을 자동으로 선택하기 때문입니다. 대신, 특정 데이터를 캐시하거나 재검증할 때를 선택하고, UI의 일부를 스트리밍할 수도 있습니다.

동적 함수

동적 함수는 사용자의 쿠키, 현재 요청 헤더 또는 URL의 검색 매개변수와 같이 요청 시간에만 알려진 정보에 의존합니다. Next.js에서 이러한 동적 함수는 아래 함수 중 어느 것을 사용하더라도 전체 라우트는 요청 시간에 동적으로 렌더링됩니다.

  • cookies()headers(): 서버 컴포넌트에서 이러한 함수를 사용하면 전체 라우트가 요청 시간에 동적 렌더링됩니다.
  • useSearchParams():
    • 클라이언트 컴포넌트에서, 정적 렌더링을 건너뛰고 대신 클라이언트에서 가장 가까운 부모 Suspense 경계까지 모든 클라이언트 컴포넌트를 렌더링합니다.
    • useSearchParams()를 사용하는 클라이언트 컴포넌트를 <Suspense/> 경계 내에 둘 것을 권장합니다. 이렇게 하면 그 위의 클라이언트 컴포넌트는 정적으로 렌더링될 수 있습니다.

스트리밍

스트리밍을 사용하면 서버에서 UI를 차례대로 렌더링할 수 있습니다. 작업은 여러 청크로 나뉘어 클라이언트에 준비될 때마다 스트리밍됩니다. 이를 통해 사용자는 전체 내용이 렌더링 완료되기 전에 페이지의 일부를 즉시 볼 수 있습니다.

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

라우트 세그먼트의 스트리밍을 시작하려면 loading.js를 사용하고, 리액트 Suspense를 사용하여 UI 컴포넌트를 스트리밍할 수 있습니다. Loading UI 및 스트리밍 섹션에서 더 많은 정보를 확인하세요.