App Router의 RSC RCC 알아보기

이규성·2025년 11월 20일
post-thumbnail

React Server Component(RSC)란?

React 18v 버전에 새롭게 추가된 컴포넌트로, 서버측에서만 실행되는 컴포넌트를 의미한다.

등장배경

Next.js 페이지 라우터 방식에서는 JavaScript 번들링 시 상호작용이 없는 컴포넌트들까지 모두 포함하여 하이드레이션을 진행했다. 이로 인해 번들 크기가 커져 Time to Interactive(TTI)가 길어지는 성능 문제가 발생했다.
이러한 문제를 해결하기 위해 상호작용이 필요 없는 컴포넌트는 서버 컴포넌트(RSC)로 분리하고 상호작용이 필요한 컴포넌트는 클라이언트 컴포넌트(RCC)로 분리하여 RSC는 서버에서만 실행하고 JavaScript 번들에서 제외함으로써, 번들 크기를 줄이고 TTI를 개선할 수 있게 되었다.

RSC RCC 렌더링 비교

서버 컴포넌트 (RSC)

  • 서버측에서 사전렌더링을 진행할 때 딱 한번만 실행 됨

클라이언트 컴포넌트 (RCC)

  • 사전렌더링에서 한 번, JavaScript 번들 하이드레이션에서 한 번으로 총 2번 실행 됨

RCC는 언제 사용하는게 좋을까?

Next.js 앱 라우터 방식에서는 모든 컴포넌트가 기본적으로 서버 컴포넌트로 생성된다. TTI를 줄이기 위해서는 클라이언트 컴포넌트 사용을 최소화하고 서버 컴포넌트를 최대한 활용하는 것이 좋다. 그렇다면 클라이언트 컴포넌트는 구체적으로 어떤 상황에서 사용해야 할까?

1. 브라우저에서만 동작하는 기능을 구현할 때

useEffect, useState와 같은 React Hook은 클라이언트 컴포넌트에서만 동작한다. 이러한 Hook을 사용해야 한다면 컴포넌트 최상단에 "use client" 지시어를 추가하여 클라이언트 컴포넌트로 명시해야 한다.

2. 사용자 상호작용이 필요할 때

화면에 렌더링한 결과물은 상호작용이 없기에 서버컴포넌트이다. 또한 a태그의 경우도 고유 HTML의 기능이기 때문에 javascript의 기능을 사용한 것이 아니기에 서버컴포넌트이다.
하지만 onClick, onChange와 같은 javascript의 이벤트 핸들러를 사용하거나 사용자 입력을 처리해야 하는 경우 클라이언트 컴포넌트가 필요하다.
예시) 검색기능이 있는 컴포넌트

주의사항

1. RSC에는 브라우저에서 실행될 코드가 포함되면 안된다

위 RCC 설명과 같이 React Hook, 이벤트 핸들러, 브라우저 전용 API 사용 시 에러가 발생한다.

2. RCC는 클라이언트에서만 실행되지 않는다

앞서 설명했듯이 RCC는 총 2번 실행된다. 사전렌더링을 위해 서버에서 1번, 하이드레이션을 위해 클라이언트에서 1번 실행된다.

3. RCC에서 RSC를 import 할 수 없다

RCC에서 RSC를 직접 import하면 해당 RSC가 자동으로 RCC로 변환된다. 이는 RSC가 JavaScript 번들에 포함되지 않도록 설계되었기 때문이다. Next.js는 개발 편의성을 위해 이를 에러로 처리하지 않고 자동 변환하지만, TTI 증가로 이어질 수 있어 주의가 필요하다.
따라서 RCC 내에서 RSC를 사용해야 한다면, import 대신 children이나 props로 전달받는 방식을 사용하는 것이 좋다.

4. RSC에서 RCC에게 직렬화 되지 않는 Props는 전달 불가하다

직렬화는 객체, 배열, 클래스 등의 복잡한 구조의 데이터를 네트워크 상으로 전송하기 위해 아주 단순한 형태(문자열, Byte)로 변환하는 것을 의미한다.
사전 렌더링 시 RSC Payload 과정을 거치는데, 이때 RSC만 따로 실행되어 데이터를 직렬화한다.
JavaScript의 함수는 값이 아닌 특수한 형태를 가졌기 때문에 직렬화가 불가능하다. 따라서 RSC에서 RCC로 함수를 Props로 전달하면 직렬화가 불가능 하기에 에러가 발생한다.

0개의 댓글