본문 바로가기

넥스트

[next.js] 14. 서버 컴포넌트

반응형
현재 포스트는 next.js 의 공식 문서를 한글로 번역하여 정리한 내용을 담고 있습니다. 공식문서를 언제든지 업데이트가 가능하므로 자세하고 정확한 내용은 공식 문서를 권장 합니다.
 

Rendering: Server Components | Next.js

Using App Router Features available in /app

nextjs.org


서버 컴포넌트(Server Components)

React 서버 컴포넌트는 서버에서 렌더링되고 필요한 경우 캐시될 수 있는 UI를 작성할 수 있게 해줍니다. Next.js에서는 렌더링 작업이 라우트 세그먼트로 더 나누어져 스트리밍과 부분 렌더링을 지원하며, 세 가지 다른 서버 렌더링 전략이 있습니다:

- 정적 렌더링(Static Rendering)
- 동적 렌더링(Dynamic Rendering)
- 스트리밍(Streaming)

이 페이지에서는 서버 컴포넌트의 작동 방식, 언제 사용해야 하는지, 그리고 서버 렌더링 전략에 대해 설명합니다.

 

  서버 렌더링(Server Rendering)의 이점

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

데이터 가져오기(Data Fetching)

서버 컴포넌트를 사용하면 데이터 가져오기를 서버에 가깝게 이동시킬 수 있습니다. 이로 인해 렌더링에 필요한 데이터를 가져오는 데 걸리는 시간과 클라이언트가 수행해야 하는 요청 수가 감소하여 성능을 향상시킬 수 있습니다.

보안(Security)

서버 컴포넌트를 사용하면 토큰 및 API 키와 같은 민감한 데이터와 로직을 클라이언트에 노출하지 않고 서버에 유지할 수 있습니다.

캐싱(Caching)

서버에서 렌더링하면 결과를 캐시하고 다음 요청 및 사용자 간에 재사용할 수 있습니다. 이로 인해 각 요청마다 수행되는 렌더링 및 데이터 가져오기 양을 줄여 성능을 향상시키고 비용을 절감할 수 있습니다.

번들 크기(Bundle Sizes)

서버 컴포넌트를 사용하면 이전에 클라이언트 JavaScript 번들 크기에 영향을 주던 큰 종속성을 서버에 유지할 수 있습니다. 이것은 느린 인터넷 또는 성능이 낮은 기기를 사용하는 사용자에게 이점을 제공하며 클라이언트가 Server Components를 렌더링하려면 JavaScript를 다운로드, 구문 분석 및 실행할 필요가 없습니다.

초기 페이지 로드 및 First Contentful Paint (FCP)

서버에서 HTML을 생성하여 사용자가 페이지를 즉시 볼 수 있도록 하여 클라이언트가 페이지를 렌더링하는 데 필요한 JavaScript를 다운로드, 구문 분석 및 실행하는 대기 없이 페이지를 볼 수 있습니다.

검색 엔진 최적화 및 소셜 네트워크 공유 가능성

렌더링된 HTML은 검색 엔진 봇이 페이지를 색인화하고 소셜 네트워크 봇이 페이지에 대한 소셜 카드 미리보기를 생성하는 데 사용할 수 있습니다.

스트리밍(Streaming)

서버 컴포넌트를 사용하면 렌더링 작업을 청크로 나누어 준비되는 대로 클라이언트로 스트리밍할 수 있습니다. 이로 인해 사용자는 페이지 전체가 서버에서 완전히 렌더링될 때까지 기다릴 필요가 없이 페이지 일부를 먼저 볼 수 있습니다.

 

  Next.js에서 Server Components 사용

기본적으로 Next.js는 Server Components를 사용합니다. 이로써 별도의 구성 없이 자동으로 서버 렌더링을 구현할 수 있으며 필요할 때 Client Components를 사용할 수 있습니다.

 

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

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

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

- React는 Server Components를 특수한 데이터 형식으로 렌더링하며 이를 React Server Component Payload (RSC Payload)라고 합니다.
- Next.js는 RSC Payload Client Component JavaScript 지침을 사용하여 서버에서 HTML을 렌더링합니다.

 

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

HTML은 초기 페이지 로드 시 빠른 비대화형 미리보기를 표시하는 데 사용됩니다.
- React Server Components 페이로드 Client 및 Server Component 트리를 조정하고 DOM을 업데이트하는 데 사용됩니다.
- JavaScript 지침 Client Components를 수화하고 애플리케이션을 상호 작용 가능하게 만드는 데 사용됩니다.

 

  React Server Component Payload (RSC)란 무엇인가요?

RSC Payload는 렌더링된 React Server Components 트리의 압축된 이진 표현입니다. 클라이언트에서 브라우저의 DOM을 업데이트하는 데 사용됩니다. RSC Payload에는 다음이 포함됩니다.

- Server Components의 렌더링 결과
- Client Components가 렌더링될 위치와 해당 JavaScript 파일에 대한 참조를 위한 플레이스홀더
- Server Component에서 Client Component로 전달된 모든 속성

 

 서버 렌더링 전략(Server Rendering Strategies)

서버 렌더링에는 정적 렌더링(Static Rendering), 동적 렌더링(Dynamic Rendering)스트리밍(Streaming)의 세 가지 하위 집합이 있습니다.

  정적 렌더링(Static Rendering, 기본값):

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

(개인 정리) 정적 렌더링은 HTML이 빌드 시간에 백그라운드에서 준비되어 완성된 결과를 브라우저에 제공하므로 SEO 최적화에 유용

 

  동적 렌더링(Dynamic Rendering):

동적 렌더링은 각 사용자에게 요청 시 라우트를 렌더링합니다. 동적 렌더링은 사용자에게 맞춤화된 데이터나 요청 시만 알 수 있는 정보(쿠키 또는 URL의 검색 매개변수 등)가 있는 경우 유용합니다.


> 캐시된 데이터를 사용한 동적 라우트(Dynamic Routes with Cached Data)

대부분의 웹 사이트에서 라우트는 완전히 정적이거나 완전히 동적이지 않습니다. 예를 들어, 캐시된 제품 데이터를 사용하여 주기적으로 재검증되는 동안 개인화되지 않은 데이터를 사용할 수 있는 전자 상거래 페이지를 가질 수 있습니다. Next.js에서는 데이터와 RSC Payload가 별도로 캐시되기 때문에 요청 시 모든 데이터를 가져오는 성능 영향을 걱정하지 않고 동적 렌더링과 정적 렌더링을 모두 사용할 수 있습니다.

 

  동적 렌더링으로 전환하기(Dynamic Rendering)

렌더링 중에 동적 함수 또는 캐시되지 않은 데이터 요청이 발견되면 Next.js는 전체 라우트를 동적으로 렌더링하도록 전환합니다. 동적 함수 및 데이터 캐싱이 정적 렌더링 및 동적 렌더링에 어떻게 영향을 미치는지에 대한 내용은 다음과 같습니다.

 

 

위 표에서 전체적으로 정적으로 렌더링되려면 모든 데이터가 캐시되어야 합니다. 그러나 동적으로 렌더링되는 동안 캐시 및 캐시되지 않은 데이터 요청을 모두 사용할 수 있습니다. 개발자로서 정적 및 동적 렌더링을 선택할 필요가 없으며 Next.js는 각 라우트에 대해 가장 적합한 렌더링 전략을 자동으로 선택합니다. 대신 특정 데이터를 캐시하거나 재검증할 때를 선택하고 UI의 일부를 스트리밍할 수 있습니다.

 

  동적 함수(Dynamic Functions)

동적 함수는 요청 시에만 알 수 있는 정보(사용자의 쿠키, 현재 요청 헤더 또는 URL의 검색 매개변수 등)에 의존합니다. Next.js에서 이러한 동적 함수는 다음과 같습니다.

- cookies() headers(): 서버 컴포넌트에서 이러한 함수를 사용하면 전체 라우트가 요청 시 동적 렌더링으로 전환됩니다.
- useSearchParams(): 클라이언트 컴포넌트에서 이 함수를 사용하면 정적 렌더링을 건너뛰고 클라이언트 컴포넌트가 클라이언트에서 가장 가까운 부모 Suspense 경계까지 렌더링됩니다. Suspense를 사용하여 useSearchParams()를 사용하는 Client Component를 래핑하는 것이 좋습니다.
- searchParams: Pages 프롭을 사용하면 페이지가 요청 시 동적 렌더링으로 전환됩니다. 이러한 함수 중 하나를 사용하면 전체 라우트가 요청 시 동적 렌더링으로 전환됩니다.

 

  스트리밍(Streaming)

 

스트리밍은 요청 시 서버에서 라우트를 렌더링하며 작업을 청크로 분할하여 클라이언트로 스트리밍합니다. 이로써 사용자는 페이지가 완전히 렌더링될 때까지 기다릴 필요 없이 페이지의 미리보기를 볼 수 있습니다. 스트리밍은 하위 우선 순위 UI 또는 전체 라우트의 렌더링을 차단하는 느린 데이터 가져오기에 의존하는 UI(제품 페이지의 리뷰와 같은)에 유용합니다.

 


Next.js에서는 loading.js를 사용하여 라우트 세그먼트를 스트리밍하고 React Suspense를 사용하여 UI 컴포넌트를 스트리밍할 수 있습니다. 더 자세한 정보는 Loading UI 및 Streaming 문서를 참조하세요.

반응형