포스트메모
    • 11월
    • 10월
    • 9월
    • 8월
    • 7월
    • 6월
    • 5월
    • 4월
    • 3월
    • 2월
    • 1월
  • 프론트엔드 관심사 분리

    25. 9. 26.

  • CSS 공부

    25. 9. 24.

  • 서버 컴포넌트와 클라이언트 컴포넌트

    25. 9. 22.

  • 프론트엔드 아키텍쳐 리팩토링의 핵심은

    25. 9. 15.

  • 함수형 프로그래밍

    25. 9. 8.

  • 사용자의 무의식을 파헤치기

    25. 9. 3.

로딩 중...

서버 컴포넌트와 클라이언트 컴포넌트

2025. 9. 22.
  • 서버 컴포넌트는 서버에서만 실행되며 번들 크기에 전혀 영향을 미치지 않습니다. 코드가 클라이언트에 다운로드되지 않으므로 번들 크기를 줄이고 시작 시간을 개선하는 데 도움이 됩니다. (참고)

  • 서버 컴포넌트는 점진적으로 렌더링되며 렌더링된 UI 단위를 클라이언트에 점진적으로 스트리밍합니다. 이를 서스펜스와 결합하면 개발자가 의도적인 로딩 상태를 만들고 페이지의 나머지 부분이 로드될 때까지 기다리는 동안 중요한 콘텐츠를 빠르게 표시할 수 있습니다.

Server Side:+-------------------------+| ServerComponent         || (Renders to HTML + RSC) |+-----------+-------------+            |            v+-------------------------+          +-------------------------------+| RSC Payload             |          | Client Component JavaScript   || (HTML + Data)           |--------->| Instructions (JS Bundles)     |+-------------------------+          +-------------------------------+Client Side:+-------------------------+| Receives HTML + JS      || Renders Non-interactive || Preview                 |+-----------+-------------+            |            v| Executes JS Instructions to hydrate Client Components |+------------------------------------------------------+
  1. React 18+: 서버 컴포넌트 chunk로 쪼개서 RSC Payload로 말아줌

RSC Payload: 서버 컴포넌트 렌더링 결과 + 클라 컴포넌트 어디에 빵꾸뚫려있는지, JS 참조 경로, 서버 컴포넌트가 클라 컴포넌트랑 연결돼있으면 전달해야하는 props 정보

  1. Next.js는 RSC Payload와 자바스크립트 설명서(a.k.a. Client Component JS Instructions)를 가지고 서버에서 HTML을 굽는다

CCJI: useState의 defaultValue,

  1. 브라우저는 Next.js 서버로부터 받은 구멍뚫린 HTML를 바로 보여준다. RSC Payload를 바탕으로 재조정(Reconciliation) 과정을 거쳐 리액트 컴포넌트 트리가 만들어지면, 이후 자바스크립트가 실행되면서 클라 컴포넌트를 구멍에 부어주고 마침내 애플리케이션이 상호작용 가능하게 된다

이걸 좀 더 이해하기 쉽게 풀어쓰자면?

  1. React Server가 React로 작성된 파일을 읽고 Virtual DOM을 만든 뒤 직렬화한다(RSC Payload).

  2. Next.js는 이걸로 만들 수 있는 HTML 뼈대를 만든다. React Server에서 만든 가상 돔에서 서버 단에서 만들 수 있는 부분들은 미리 렌더링하는 것이다.

  3. 서버에서 렌더링할 수 있는 부분이 더이상 없다면 렌더링 결과물과 서버용 노드들이 발라진 RSC Payload를 클라이언트(브라우저)로 던진다. 클라이언트는 직렬화된 나머지를 받아 파싱하고 익히 아는 Critical Render Path를 거쳐 나머지 렌더링을 재개하는 것이다.

그럼 React Server는 어떻게 React 코드를 직렬화하는 것일까? JSON.stringify()를 쓰면 알 수 있듯 함수나 조금만 복잡한 객체는 모두 직렬화가 불가능하다는 사실을 잘 알고 있다. React 코드는 대부분이 컴포넌트나 훅과 같은 함수다.

React server는 이런 것들을 만났을 때 억지로 직렬화하지 않고 번들러의 도움을 받아 해당 컴포넌트가 존재하는 파일 경로를 대신 끼워넣는다.


Why would we want this?

왜 우리는 이걸(RSC) 해야할까요?

Before React Server Components, all React components are “client” components — they are all run in the browser. When your browser visits a React page, it downloads the code for all the necessary React components, constructs the React element tree, and renders it to the DOM (or hydrates the DOM, if you’re using SSR). The browser is a good place for this, because it allows your React application to be interactive — you can install event handlers, keep track of state, mutate your React tree in response to events, and update the DOM efficiently. So why would we want to render anything on the server?

RSC가 있기 전, 모든 React Component들은 브라우저에서 동작하는 "client" 컴포넌트들이었습니다. 당신의 브라우저가 리액트 페이지를 방문할 때면, 당신의 브라우저는 React Component에 필요한 모든 코드들을 다운로드 받고 이를 React element tree로 구조화했으며 DOM으로 렌더하곤 했습니다(만약 SSR을 채택했다면 DOM을 hydrate했겠죠). 브라우저는 앞서 말한 것들의 최적의 장소였습니다. 왜냐면 브라우저는 당신의 리액트 앱이 인터랙티브하게 해주니까요. 당신은 브라우저를 통해 이벤트 핸들러들을 끼울 수 있고, 상태를 유지하며, 이벤트의 결과를 React tree에 반영하고 DOM을 효율적으로 업데이트할 수 있어요. 그럼 도대체 왜 우리는 서버에서 무언가를 렌더하고 싶을까요?

There are certain advantages that rendering on the server has over the browser:

서버에서 렌더링하는 것이 브라우저에서 하는 것보다 확실히 나은 점들이 몇가지 있습니다.

  • The server has more direct access to your data sources — be they your databases, GraphQL endpoints, or the file system. The server can directly fetch the data you need without hopping through some public API endpoint, and it is usually more closely colocated with your data sources, so it can fetch the data more quickly than a browser can.

서버는 db, GraphQL 엔드포인트나 파일시스템 등 데이터 소스에 좀 더 직접적으로 접근할 수 있습니다. 서버는 퍼블릭 API 엔드포인트를 거치지 않고서도 당신이 필요한 데이터를 직접 패치해올 수 있습니다. 그리고 대부분의 경우 이 방식은 당신의 데이터 소스와 물리적으로 가깝기 때문에, 브라우저보다 더 빨리 데이터를 패치해올 수 있습니다.

  • The server can cheaply make use of “heavy” code modules, like an npm package for rendering markdown to html, because the server doesn’t need to download these dependencies every time they’re used — unlike the browser, which must download all used code as javascript bundles.

서버는 md를 html로 렌더링하는 npm 패키지같은 무거운 코드 모듈을 사용하는 비용에 있어 더 저렴합니다. 왜냐면 서버는 매번 필요한 코드들을 자바스크립트 번들로 다운로드해야하는 브라우저와 달리 의존성을 한 번만 다운로드 받으면 되니까요.

In short, React Server Components makes it possible for the server and the browser to do what they do best. Server components can focus on fetching data and rendering content, and client components can focus on stateful interactivity, resulting in faster page loads, smaller javascript bundle sizes, and a better user experience.

요약하자면, React Server Component는 서버와 브라우저가 각자 가장 잘할 수 있는 것들만 할 수 있도록 합니다. 서버 컴포넌트는 데이터 패칭과 콘텐츠 렌더링에 집중하고, 클라이언트 컴포넌트는 stateful한 상호작용성에 집중하여 가벼워진 자바스크립트 번들 사이즈와 더 빠른 페이지 로드를, 그리고 더 나은 사용자 경험을 만들어낼 수 있다는 겁니다.


왼쪽 화살표프론트엔드 아키텍쳐 리팩토링의 핵심은CSS 공부오른쪽 화살표