[Next.js] 리액트서버컴포넌트(RSC)와 서버사이드렌더링(SSR)은 어떻게 다른 걸까?

youznn·2024년 8월 8일
0

Next JS

목록 보기
4/4

그만 보고 싶다…

An error occurred in the Server Components render.

ㅠㅠ

저희 서비스의 stage 환경에서 서버 컴포넌트 렌더링 에러가 잊을만하면 발생하고 있습니다. 😂 프론트엔드쪽 에러인지, 백엔드쪽 에러인지, 또는 인프라쪽 에러인지 확신할 수 없는 경우도 많습니다. 그렇다면 도대체 저 에러 메시지에서 보이는 ‘Server Components Render’란 무엇일까요?

먼저 간단한 용어 정리를 하고 넘어가겠습니다.

SSR - Server Side Rendering

CSR - Client Side Rendering

RSC - React Server Component

또한 웹사이트 속도 측정에 쓰이는 값들은

다음과 같습니다.

SSR? CSR?

들어가기에 앞서, 서버사이드렌더링(SSR)을 이해하는 것은 서버 컴포넌트를 이해하는 데에 도움이 됩니다. 몇 년 전의 리액트는 대부분 ‘클라이언트사이드렌더링(CSR)’을 사용했습니다. 애초에 React는 클라이언트 사이드 UI 라이브러리로 시작됐다고 합니다.

CSR

CSR은 말 그대로 클라이언트 쪽에서 일어나는 렌더링을 말합니다. 서버는 요청을 받으면 클라이언트에 HTML과 JS 파일을 보내줍니다. 클라이언트는 파일을 모두 받은 뒤에 렌더링을 시작하게 됩니다. 클라이언트 측에서 다운로드가 완료된 Javascript가 실행되면 데이터를 위한 API가 호출되고, API가 불러와지면 상호작용이 가능해지게 됩니다.

👍 이러한 CSR의 장점은 무엇일까요?

첫째로, 상호작용이 향상됩니다. CSR은 사용자의 인터랙션에 따라 실시간으로 컨텐츠가 변경되기 때문에 깜박임 없는 부드러운 화면 전환을 제공합니다.

둘째로, 서버 부하가 감소됩니다. 클라이언트에서 컨텐츠를 렌더링하기 때문에 서버의 부하가 줄어들고, 서버가 더 많은 요청을 처리할 수 있습니다.

또한 컨텐츠의 첫 데이터를 클라이언트가 받는데 걸리는 시간인 TTFB(Time To First Byte)가 짧아 좋습니다.

👎 그러나 클라이언트 측에서 데이터를 모두 받은 후 렌더링하기 때문에 컨텐츠가 처음 보이기 시작하는 시간인 FCP(First Contentful Paint)측면이 좋지 않습니다.

SEO(검색엔진최적화) 문제도 있습니다. content가 실시간으로 생성되기 때문에 봇이 크롤링하기 어렵기 때문입니다.

마지막으로 클라이언트 쪽에서 렌더링을 수행하기 때문에, 사용자의 기기 성능에 따른 속도 문제가 발생할 수 있습니다.

SSR

SSR의 과정은 다음과 같습니다. 서버는 즉시 렌더링 가능한 html 파일을 만들어 클라이언트에게 전달합니다. CSR과는 달리, 클라이언트에게 전송되는 순간 HTML이 즉시 렌더링 됩니다. 그리고 나서 JS를 다운로드 받는데, 다운로드 되는 동안 클라이언트는 컨텐츠를 볼 수는 있지만 조작하지는 못합니다. 브라우저가 JS까지 모두 다운로드 받고 컴파일 되면, 그때 페이지는 상호작용가능해집니다.

따라서 SSR을 사용하면 초기 로딩 속도가 빠르고, 이미 HTML 안에 컨텐츠가 있기 때문에 SEO에 유리합니다.

그러나 매번 서버에 요청을 보낼 때마다 서버에서 모두 렌더링 된 HTML 파일을 받아와야 하기 때문에 TTFB가 느리고 깜빡임 등의 UX적인 측면에서 주의가 필요합니다.

Next JS APP 라우터(코드당 사용)는 기본적으로 SSR을 제공하며, Server side Render 이후 Hydration 과정을 거쳐 상호작용가능한 UI가 됩니다.

여태까지 서버사이드렌더링, 클라이언트사이드 렌더링에 대해 알아봤습니다.


RSC

그렇다면, RSC(리액트 서버 컴포넌트)란 무엇일까요? 얼핏 보면 서버사이드렌더링과 동일한 개념이라고 생각할 수도 있겠지만, 둘은 다른 개념입니다. SSR과 RSC는 상호보완적인 관계라고도 하네요.

SSR은 주로 HTML 렌더링과, RSC데이터 페칭과 관련이 깊다고 생각하시면 편할 것 같습니다.

NextJS에서 추천하는, 서버 컴포넌트와 클라이언트 컴포넌트를 사용하는 경우를 볼까요?

이미지 출처-NextJS 공식문서

리액트 서버 컴포넌트들은 서버에서 렌더되고 페치됩니다.

client component와 비교한 RSC의 장점은 다음과 같습니다.

  1. Bundle Sizes

    기존에는 웹에서 사용되는 JavaScript 코드와 라이브러리들이 클라이언트 측으로 번들링되어야 했습니다. 이러한 번들은 사용자의 브라우저에서 다운로드되어야 했고, 이는 느린 네트워크 연결이나 제한된 디바이스 성능으로 인해 사용자 경험을 저하시킬 수 있었습니다.

    하지만 Next.js는 서버 컴포넌트를 사용함으로써 dependency들을 서버측에 유지할 수 있게 합니다. 클라이언트는 어떠한 Javascript들도 다운로드, 구문 분석, 실행할 필요가 없습니다. 그래서 실제로 SSR을 사용했을때보다 훨씬 작은 번들크기를 가지며 이로 인하여 매우 빠른 TTI 시간을 가지게 됩니다.

    +) RSC는 hydration 단계 없이 컴포넌트로서의 역할을 수행합니다

  2. client side에서 fetch할때 발생하는 waterfall 현상이 존재하지 않습니다.

    기존 fetch를 여러개 하여 오래 걸리는 api가 있다면 waterfall(부모컴포넌트렌더→자식컴포넌트렌더→자식렌더→ ..) 때문에 blocking되는 현상이 발생하는데요. server에서는 이러한 문제가 없기때문에 서버에서 호출하고 서버에서 html을 그리는 서버 컴포넌트는 waterfall 현상이 일어나지 않습니다.

  3. Security

    서버 컴포넌트들은 API 토큰과 같은 민감한 데이터나 로직을 클라이언트에 노출될 위험 없이 서버에서 보관합니다.

DB / 내부 서비스 / 파일 시스템 같은 server-only data 사용 가능


코드당에서는 언제 RSC를 사용할까?

NextJS 13 이후로는 모든 컴포넌트가 기본적으로 RSC입니다. 하지만 클라이언트와의 상호작용이 필요하거나 state를 사용해야 하는 컴포넌트에는 클라이언트 컴포넌트가 적용됩니다.

즉, RSC가 default이므로 client component로 사용 시에는

다음과 같이 상단에 ‘use client’를 명시해 주어야 오류가 뜨지 않습니다. 해당 컴포넌트는 problemInfinteTable로, 유저가 페이지 하단에 닿을 때의 interaction에 따라 데이터 페칭을 요청하는 ‘무한스크롤’이기 때문에 client component입니다.

server component는 하위 컴포넌트로 client component를 가질 수 있지만, client component는 server component를 자식으로 가질 수 없고 client component의 하위 컴포넌트들은 모두 client component로 여겨지기 때문에, 최대한 leaves에서 client component를 정의하여 사용하도록 합니다.

그래서 server component rendering error가 발생하는 이유는…

사실 ‘서버 컴포넌트’가 ‘렌더링 및 페칭’되는 과정에서 발생할 수 있는 원인은 너무 많습니다. api 요청이 잘못되었을 때, 의존성 충돌, 구성 파일 오류, 서버 환경 문제, 데이터베이스 문제, 등등….

명쾌한 해답은 내릴 수 없지만, 서버 컴포넌트와 서버 사이드 렌더링이 무엇인지 아는 데에 조금이나마 도움이 되길 바랍니다…!


출처

https://medium.com/walmartglobaltech/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8

https://www.freecodecamp.org/korean/news/how-to-use-react-server-components/

profile
https://github.com/youznn

0개의 댓글