노트

RSC 페이로드(Flight)

RSC Payload

프런트엔드#react#nextjs · 연결된 개념 13개

쉽게 말하면

RSC 페이로드는 서버 컴포넌트가 만든 결과를 보내려고 적은 포장 목록표 같은 데이터예요. HTML이 아니라 React가 읽는 줄 단위 목록이라, 브라우저가 이걸 보고 화면 트리를 다시 조립해요.

비유가 깨지는 곳 목록에 모든 걸 담지는 못해요. 클라이언트 컴포넌트는 코드 대신 참조로만 들어가고 넘기는 props는 직렬화할 수 있어야 해요. 준비 안 된 부분은 자리표시자를 먼저 보내고 나중에 채워요.

RSC(React Server Components) 페이로드는 서버 컴포넌트를 실행한 결과(엘리먼트 트리, props, 클라이언트 컴포넌트 참조)를 네트워크로 보내려고 직렬화(Serialization)한 데이터다. 흔히 Flight 형식이라 부른다. HTML(HyperText Markup Language)이 아니라 React가 클라이언트에서 트리를 다시 만드는 데 쓰는 줄 단위 스트림이다. 세부 형식은 React 버전마다 바뀐다(아래는 2026년 기준의 대략적인 모양).

1:I["./LikeButton.js",["chunk-3f2.js"],"default"]
0:["$","div",null,{"className":"card","children":[
    ["$","h2",null,{"children":"제목"}],
    ["$","$L1",null,{"count":3}]]}]
  • 줄 = 청크: ID:태그+JSON 꼴이다. ID가 있어서 청크끼리 서로를 가리킬 수 있다
  • 태그: 없으면 일반 데이터나 엘리먼트, I는 클라이언트 모듈 참조, H는 CSS(Cascading Style Sheets)·폰트 미리 받기 힌트, E는 에러, D는 개발용 디버그 정보
  • $ 접두사: "$"는 엘리먼트 표시, "$L1"은 아직 안 온 청크 1의 지연 참조, "$@1"은 Promise, "$h"는 서버 함수 참조(이전 버전은 "$F"), "$Sreact.suspense"는 심볼이다. 진짜 $로 시작하는 문자열은 $$로 이스케이프한다

엘리먼트 객체와의 대응

["$", type, key, props] 배열은 React 엘리먼트 객체 { $$typeof, type, key, props }를 그대로 옮긴 것이다. JSON(JavaScript Object Notation)으로 못 만드는 것만 바뀐다. $$typeof 심볼은 "$" 마커가 되고, 함수인 클라이언트 컴포넌트는 코드 대신 I 청크 참조($L1)가 된다. 서버 컴포넌트는 서버에서 이미 실행돼 사라지고, 반환한 엘리먼트들이 펼쳐져 담긴다. 그래서 클라이언트 컴포넌트에 넘기는 props는 직렬화할 수 있어야 한다.

스트리밍

먼저 $L1 같은 자리표시자를 보내고, 서버에서 그 데이터가 준비되면 같은 ID의 청크를 나중에 흘려보낸다. 클라이언트는 도착하는 대로 참조를 채운다. Suspense 경계가 자리표시자 자리다(스트리밍 SSR, Suspense). Next.js는 첫 로드 때 페이로드를 HTML 안의 self.__next_f.push(...) 스크립트로 넣고, 이후 이동 때는 페이로드만 따로 받는다.

같은 트리의 두 상태라고 보면 된다. 메모리 속 살아 있는 객체가 Virtual DOM이고, 그것을 네트워크로 옮기려고 문자열로 만든 것이 페이로드다. 직렬화와 원격 호출의 일반론은 RPC.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

  • 부수 효과와 Effect

    부수 효과(Side Effect)는 함수가 값을 계산해 돌려주는 본업 외에 바깥 세계를 건드리는 모든 동작이다. React의 Effect(useEffect로 감싼 코드)는 그중에서도 렌더가 끝난 뒤 외부 시스템과 맞추려고 실행하는 부수 효과만 가리키는 좁은 이름이다. 즉 Effect는 부수 효과의 부분집합이다.

  • Pages Router에서 App Router로

    App Router는 Next.js 13에서 도입된 app/ 디렉터리 기반 라우터로, 서버 컴포넌트·중첩 레이아웃(Nested Layouts)·스트리밍을 기본으로 한다. pages/ 기반의 Pages Router에서 옮길 때 바뀌는 생각을 정리한다.

  • NestJS

    NestJS는 TypeScript를 전제로 모듈·의존성 주입(Dependency Injection, DI)·데코레이터(decorator) 구조를 제공하는 Node.js 서버 프레임워크다. 2017년 Kamil Myśliwiec가 만들었고, 구조를 강제하는 방식 때문에 흔히 "Node.js의 Spring"이라 불린다.

  • Activity와 숨겨진 라우트 보존

    Activity는 React 19.2의 컴포넌트로, UI를 언마운트하지 않고 display: none으로 숨기면서 state와 DOM(Document Object Model)을 보존한다. 숨기는 동안 Effect는 정리(cleanup)된다. 예전 이름은 Offscreen이다.

보기 옵션