- 서버 컴포넌트를 사용하면 서버에서 렌더링하고 선택적으로 캐시가 가능한 UI를 만들수있다
- 렌더링은 스트리밍과 부분렌더링을 위해 경로별로 더 분할된다
- 아래는 서버렌더링을 위한 3가지 전략이다
- 정적 렌더링
- 동적 렌더링
- 스트리밍
- 예를 들어 DB와 서버를 더 가까운곳에 두어서 레이턴시를 줄일 수 있다
- 렌더링에 필요한 데이터 로딩시간과 클라이언트의 호출 회수가 줄어든다
- 토큰, API키 등 민감한 데이터를 클라이언트에 노출시키지 않아도 된다
- 데이터 로딩 결과를 캐싱해서 후속 작업 및 사용자 전체에게 재사용이 가능
- 각 요청마다 수행되는 렌더링과 데이터 로딩의 양이 줄어들어 성능개선 및 비용절감 가능
- 기본으로 성능을 최적화하기 위한 도구를 지원해줌
- 클라이언트 컴포넌트에서 많은 양의 번들을 로딩하지 않기 때문에 성능이 향상된다
- 서버는 클라이언트 처럼 페이지를 렌더링 하기위해 JS 다운로드, 구문 분석 등이 필요없고 유저가 바로 볼 수 있는 HTML을 반환한다
- 정적 HTML을 생성하므로 SEO에 최적화 되어있다
- 소셜 서비스에서 카드 미리보기 생성에도 좋다
- 렌더링 작업을 청크로 분할하여 완료된것만 먼저 클라이언트에 렌더링이 가능하다
- 유저는 모든 페이지의 로딩을 기다리지 않고 완료되는대로 볼 수 있다
- 기본적으로 모두 서버 컴포넌트로 되어있다
- 선택적으로
"use client"
를 통해서 클라이언트 컴포넌트도 사용이 가능하다
- 서버에서는 React API를 활용하여 스트리밍을 관리한다
- 청크는 2개의 단계로 렌더링된다
- 리액트는 서버 컴포넌트를 RSC Payload라는 특수한 형태로 렌더링한다
- Next.js는 RSC와 자바스크립트를 이용하여 HTML을 생성한다
- HTML은 초기 페이지 로드시에 빠르게 화면을 보여주기 위해서 사용된다
- RSC Payload는 서버 컴포넌트 트리와 DOM을 업데이트 하는데 사용된다
- 이후에 자바스크립트를 통해 상호작용이 가능하도록 hydration 한다
- 정적 렌더링은 빌드 또는 데이터 갱신이세 백그라운드에서 렌더링이 발생한다
- 빌드된 결과는 캐싱되어 CDN에 배포된다
- 유저와 서버 요청간에 데이터 공유가 가능해진다
- 보통 유저에게 맞춤화되지 않고 블로그나 상품페이지 등 빌드시점에 확인 가능한 데이터가 있는 경우에 유용하다
- 각 요청에 의해서 동적으로 렌더링된다
- 경로에 사용자에게 맞춤화된 데이터나 쿠키, URL 등 요청 시점에만 알 수 있는 정보가 있을떄 유용함
- 렌더링할때 동적 함수나 캐시되지 않은 데이터 요청이 발견되면 전체 경로를 동적으로 렌더링한다
- 아래 표는 동적 함수와 데이터캐싱의 경로가 정적 또는 동적으로 렌더링되는지에 대한 표다
동적함수 | 데이터 | 라우트 |
---|---|---|
없음 | 캐싱됨 | 정적 렌더링 |
있음 | 캐싱됨 | 동적 렌더링 |
없음 | 캐싱안됨 | 동적 렌더링 |
있음 | 캐싱안됨 | 동적 렌더링 |
위 표에서 보면 경로가 완전 정적이 될려면 모든 데이터가 캐싱되어 있아야한다
하지만 캐싱된 데이터와 안된 데이터를 모두 사용하는 동적 렌더링도 가능하다
Next.js는 가장 적합한 렌더링 전략으로 자동으로 선택해주므로 개발자가 고민할 필요는 없다
대신 특정 데이터를 캐싱하거나 재검증 시기를 선택하고 UI의 일부를 스트리밍 할 수 있다
- 동적함수는 request header나 쿼리 등 요청시점에만 알 수 있는 정보에 의존한다
cookies
,headers
,searchParams
를 사용하게되면 동적렌더링으로 전환된다
- 스트리밍을 사용해서 서버에서 UI를 점전직으로 렌더링이 가능하다
- 작업이 완료되는 대로 청크로 분할되어 클라이언트로 스트리밍 된다
- 모든 콘텐츠가 로딩되기 이전에 페이지의 일부를 즉시 볼 수 있음
Next.js에서는 기본적으로 스트리밍을 제공하고 Suspense 및 loading.ts를 통해서 스트리밍이 가능함