노트

Fiber 아키텍처

React Fiber Architecture

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

쉽게 말하면

Fiber는 React가 큰 렌더 작업을 잘게 쪼개 둔 할 일 카드 묶음이에요. 긴 숙제를 문제 단위로 나눠 두면 급한 전화를 받고 와서 이어 풀 수 있듯, 렌더 도중에도 사용자 입력을 먼저 처리해요.

비유가 깨지는 곳 멈춰도 반쯤 푼 답안을 내진 않아요. 화면용 current와 작업용 workInProgress 두 트리를 둬요. 작업 트리가 완성되면 커밋 단계에서 포인터만 바꿔서, 반쯤 그린 화면은 보이지 않아요.

Fiber는 React 16부터 쓰는 내부 자료구조이자 렌더링 엔진이다. 엘리먼트마다 Fiber 노드를 만들어 렌더 작업을 작은 단위로 쪼개고, 우선순위를 매기고, 중간에 멈췄다 다시 이어 갈 수 있게 한다.

  • 왜 생겼나: React 15까지는 렌더를 한 번 시작하면 트리 끝까지 동기로 돌았다. 큰 목록을 그리는 동안 메인 스레드가 막혀 입력과 스크롤이 끊겼다(이벤트 루프)
  • 작업 단위: 큰 렌더 하나를 Fiber 단위의 작은 일로 나눈다. 그 사이에 더 급한 일(사용자 입력)을 먼저 처리할 수 있다(동시성 렌더링)
  • 연결 리스트(Linked List) 구조: 각 Fiber는 child(첫 자식), sibling(다음 형제), return(부모)로 이어져 있어서, 재귀 호출 없이 어디서든 멈추고 이어 갈 수 있다(연결 리스트, 트리 순회)
  • 주요 필드: type, key, stateNode(실제 DOM(Document Object Model) 등), pendingProps·memoizedProps, memoizedState(훅 상태), alternate

두 단계와 더블 버퍼링(Double Buffering)

  • Render 단계(Render Phase): 새 트리를 계산하고 바뀐 점을 모은다. DOM을 건드리지 않으며 중단될 수 있다. 그래서 렌더 함수는 순수해야 한다(React의 규칙과 렌더 순수성)
  • Commit 단계(Commit Phase): 모은 변경을 실제 DOM에 한 번에 반영한다. 중단할 수 없다

React는 트리를 두 벌 둔다. 화면에 반영된 current와, 렌더 단계에서 짓는 workInProgress다. 커밋할 때 포인터만 바꿔 끼운다. 그래픽스의 더블 버퍼링(보이는 앞 버퍼와 그리는 중인 뒤 버퍼를 나눠 다 그린 뒤 교체)과 같은 구조라서, 렌더가 도중에 버려져도 사용자는 반쯤 그려진 화면을 보지 않는다. 두 트리의 대응 노드는 alternate로 이어져 재사용된다.

flowchart TD
  U[업데이트] --> R["Render 단계: workInProgress 트리를 짓고 바뀐 점을 모음"]
  R -- 중단·버림 --> K["current 그대로 (반쯤 그린 화면은 안 보임)"]
  R --> C["Commit 단계: 모은 변경을 DOM에 한 번에 반영 (중단 불가)"]
  C --> S["포인터 교체: workInProgress가 새 current"]
  S -. 다음 업데이트 .-> U

Suspense, useTransition, 스트리밍 SSR, 선택적 하이드레이션이 모두 이 위에서 동작한다. 엘리먼트와의 관계는 React 엘리먼트와 JSX.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 서버 렌더에서 훅이 하는 일

    서버 렌더(Server-Side Rendering, SSR)에서도 컴포넌트 함수는 실제로 호출되고, 그 안의 훅도 호출은 된다. 다만 서버에는 커밋(DOM 반영)이 없어서, 렌더 중 동기적으로 값을 계산하는 훅만 일하고 커밋 뒤에 도는 훅은 아무것도 하지 않는다. "이 훅은 클라이언트에서만 동작한다"는 말은 대개 "Effect 안의 일은 클라이언트에서만 일어난다"는 뜻이다.

  • 부수 효과와 Effect

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

  • Effect가 필요 없는 경우

    Effect는 외부 시스템과 동기화할 때 쓰는 탈출구(Escape Hatch)다. 렌더 중에 계산할 수 있는 값이나 사용자 이벤트 처리에 Effect를 쓰면 렌더가 한 번 더 일어나고 흐름이 꼬인다. React 공식 문서가 이런 경우를 따로 정리해 두었다.

  • React 서버 컴포넌트(RSC)

    React 서버 컴포넌트(React Server Components, RSC)는 서버에서만 실행되고, 컴포넌트 코드가 아니라 실행 결과(직렬화된 엘리먼트 트리)만 클라이언트로 보내는 컴포넌트다. Next.js App Router에서는 'use client'를 붙이지 않은 컴포넌트가 기본으로 서버 컴포넌트다.

  • 브라우저 렌더링 파이프라인

    브라우저가 받은 HTML·CSS·JS를 화면의 픽셀로 바꾸는 순서. 처음 로드할 때도, 이후 무언가 바뀔 때도 같은 단계를 거친다. 바뀐 내용에 따라 어느 단계부터 다시 시작하는지만 다르다.

보기 옵션