[번역] 서버 컴포넌트

Next.js
2024-03-11

원글 : https://nextjs.org/docs/app/building-your-application/rendering/server-components#how-are-server-components-rendered

리액트 서버 컴포넌트는 서버에서 렌더링되고 선택적으로 캐시된 UI를 만들 수 있게 한다.

Next.js에서 렌더링 하는 것은 route segments에 의해 더 나누어져있어서 streaming, 부분적 렌더링, 그리고 세가지 다양한 서버 렌더링 전략을 가능하게 한다.

  • Static Rendering
  • Dynamic Rendering
  • Streaming

서버 렌더링의 장점

  • 데이터 fetching : 서버 컴포넌트는 데이터 소스(아마 DB)와 가까운 서버에서 data fetching할 수 있게 한다. 렌더링에 필요한 데이터를 fetch하는 데 걸리는 시간과 클라이언트가 요청해야 하는 향을 줄여 성능을 향상시킬 수 있다.
  • 보안 : 서버 컴포넌트 토큰과 API keys들과 같은 중요한 데이터나 로직을 클라이언트에 노출할 위험 없이 보관할 수 있게 해준다
  • Caching : 서버에서 렌더링함으로써, result를 캐싱하여, 후속 요청과 사용자 간에 재사용될 수 있다. 이것은 각 요청에 대해 수행되는 렌더링 및 데이터 fetching 렌더링의 양을 줄여 성능을 향상시키고 비용을 절감할 수 있다.
  • 번들 사이즈 : 서버 컴포넌트는 이전에 서버의 자바스크립트 번들 사이즈에 영향을 주었던 큰 dependencies을 사용할 수 있게 해준다. 클라이언트가 서버 컴포넌트의 자바스크립트를 다운로드, parse 그리고 실행할 필요가 없기 때문에 느린 인터넷 혹은 성능이 좋지 않은 디바이스를 가진 유저들에게 유용하다.
  • Initial Page Load 와 First Contentful Paint(FCP) : 서버에서 HTML을 만들어 사용자가 페이지를 렌더링하는데 필요한 자바스크립트를 다운로드, parse, 실행할 때까지 기다리지 않고 즉시 페이지를 보여줄 수 있다.
  • SEO와 Social Network Shareability
  • Streaming : 서버 컴포넌트는 렌더링 작업을 청크로 나누어 준비가 되면 클라이언트에게 stream할 수 있다. 이렇게하면 전체 페이지가 서버에서 렌더링될 때까지 기다리지 않고 유저들에게 페이지의 일부를 일찍 볼 수 있게 한다.

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

서버에서 Next.js는 리액트의 API들을 사용하여 렌더링을 조정한다. 렌더링 작업은 개별 route segments와 Suspense Boundaries에 의해 청크로 나누어진다

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

  1. 리액트는 서버 컴포넌트를 React Server Component Payload(RSC Payload)로 불리는 특별한 데이터 포멧으로 렌더링한다.
  2. Next.js는 이 RSC Payload와 클라이언트 컴포넌트 자바스크립트 instructions를 사용하여 서버에서 HTML을 렌더링한다.

그리고나서 클라이언트에서

  1. 그 HTML은 즉시 빠른 route의 non-interactive preview를 보여주는데 사용된다. - 이것은 초기 페이지에서만 적용된다.
  2. RSC Payload는 클라이언트와 서버 컴포넌트 트리들을 조정하는데 사용되고 DOM이 업데이트된다.
  3. 자바스크립트 지시는 클라이언트를 hydrate하는데 사용되고 애플리케이션을 인터랙티브하게 만든다.

RSC Payload란? : 렌더링된 RSC 트리의 컴팩트한 바이너리 표현이다. 클라이언트에서 리액트가 브라우저의 DOM을 업데이트하는데 사용된다.

RSC Payload는 다음을 포함한다:

  1. 서버 컴포넌트의 렌더링 결과
  2. 클라이언트 컴포넌트를 렌더링할 placeholders 및 자바스크립트 파일에 대한 참조
  3. 서버 컴포넌트에서 클라이언트 컴포넌트로 전달된 props

서버 렌더링 전략

서버 렌더링에는 3가지의 하위 집합의 집합이 있다: 정적, 동적, 스트리밍

정적 렌더링 (기본)

정적 렌더링을 사용하면, 라우트들은 빌드 타임 혹은 data revalidation 후 background에서 렌더링된다. 이 결과는 캐시되고 CDN에 푸시된다.

이 최적화를 통해 사용자와 서버 요청 간에 렌더링 작업의 결과를 공유할 수 있다.

정적 렌더링은 라우트가 유저에게 개별화되지 않은 데이터를 가지고 있을 때와 빌드 타임에 알려질 수 있는, 예를 들어 정적 블로그 혹은 프로덕트 페이지에 유용하다.

동적 렌더링

동적 렌더링을 사용하면, 라우트들은 각 유저들이 요청 할 때 렌더링된다.

동적 렌더링은 유저가 개인화된 데이터를 가지고 있을 때 혹은 request time에서만 생성되는 정보를 가지고 있을 때 유용하다. 예를 들어 쿠키 혹은 URL searchparams

캐시된 데이터의 동적 렌더링

대부분의 웹사이트에서 라우트들은 완전히 정적이거나 동적이지 않다 - 섞여있다.

예를 들어, e-commerce 페이지를 생각해보면, 이 페이지는 특정 주기에 revalidated되는 캐시된 프로덕트 데이터를 사용하기도 하고 캐시되지 않는, 개인화된 customer 데이터를 사용한다.

Next.js에서는, 캐시되고 캐시되지 않는 데이터가 모두 있는 라우트를 동적으로 렌더링할 수 있다. 이는 RSC Payload와 데이터가 별도로 캐시되기 때문입니다. 이를 통해 요청 시 모든 데이터를 가져올 때의 성능 영향에 대한 걱정 없이 동적 렌더링을 선택할 수 있습니다.

동적 렌더링으로 전환

렌더링하는 동안, 만약 동적 함수 혹은 캐시되지 않는 데이터 요청이 발견되면, Next.js는 전체 라우트를 동적으로 렌더링하게 전환할 수 있다.

route를 완전히 정적이 되려면 모든 데이터가 캐시되어야 하지만,

캐시된 data fetches와 캐시되지 않은 data fetches를 모두 사용하는 동적으로 렌더링된 route를 가질 수 있다.

Next.js는 사용되는 특징과 API를 기반으로 라우트별 최적의 렌더링 전략을 자동으로 선택해준다. 대신 특정 데이터를 캐시하거나 재검증할 시점을 선택하고, UI의 일부를 스트리밍할 수 있습니다.

동적 함수

동적 함수는 유저의 쿠키, 현재 요청 headers, 혹은 URL의 search params와 같은 각 요청 마다 새로운 정보에 의존한다.

Next.js에서 이 동적 함수는 아래와 같다

  • cookies()headers() : 서버 컴포넌트에서 이 함수를 사용하면 request time때 전체 라우트가 동적으로 선택될 것이다.
  • useSearchParams() :
    • 클라이언트 컴포넌트에서, 정적 렌더링을 스킵하고 대신 클라이언트에서 가장 가까운 상위 Suspense boundary까지 모든 클라이언트 컴포넌트를 렌더링할 것이다.
    • useSearchParams() 를 사용하는 클라이언트 컴포넌트를 <Suspense/> boundary에서 래핑하는 것이 좋다 이렇게 하면 위의 클라이언트 컴포넌트를 정적으로 렌더링할 수 있다.
  • searchParams : 페이지의 prop를 사용하면 요청 시 페이지를 동적 렌더링으로 적용할 수 있다.

이 함수들을 사용하면 요청 때 전체 라우트를 동적 렌더링으로 적용할 수 있다.

스트리밍

스트리밍을 사용하면, 라우트들은 요청 때 서버에서 렌더링된다. 이 작업은 청크로 나누어지고, 준비가 되면 클라이언트에서 스트림된다. 이것은 유저가 완전히 렌더링되기 전에 페이지를 볼 수 있게 해준다.

스트리밍은 더 낮은 우선순위의 UI 혹은 전체 라우트 렌더링을 block할 수 있는 느린 데이터 fetches에 의존한 UI에 유용하다. 예를 들어, 프로덕트 페이지에서 reviews

Next,js에서 loading.js 를 사용해 라우트 segments와 React Suspense를 사용해 UI 컴포넌트를 스트림할 수 있다.

관련 포스트

post thumbnail

[번역] Next.js 14

Next.js 14는 다음과 같은 가장 중점으로 둔 릴리스이다. - Turbopack: App & Pages Router에서 5,000번의 테스트 통과 - 로컬 서버 시작이 53%

2024-03-12
post thumbnail

[번역] 캐싱

Next.js는 렌더링 작업과 데이터 요청을 캐싱하여 어플리케이션의 성능을 향상시키고 비용을 감소시킨다. 기본적으로 Next.js는 성능을 향상시키고 비용을 줄이기 위해 가능한 한

2024-03-12
post thumbnail

[번역] 구성 패턴

리액트 애플리케이션을 빌드할 때, 애플리케이션의 어느 부분을 서버 또는 클라이언트에서 렌더링할지 고려해야 한다. 이 글은 서버 및 클라이언트 컴포넌트를 사용할 때 권장되는 몇 가지

2024-03-11
post thumbnail

[번역] 클라이언트 컴포넌트

클라이언트 컴포넌트는 요청 시 클라이언트에서 렌더링할 수 있는 인터랙티브한 UI를 만들 수 있게 해준다. Next.js에서 클라이언트 렌더링은 opt-in으로, 리액트가 클라이언트

2024-03-11

도로모의 기술 블로그

# Contact : jyw966@naver.com

Copyright © doromo. All Rights Reserved.