React Fiber는 렌더링 작업을 작은 단위로 나누고 우선순위에 따라 처리함으로써, 무거운 업데이트 중에도 UI가 끊기지 않도록 설계된 React의 새로운 재조정 엔진입니다.
React Fiber
React Fiber는 React 16버전부터 도입된 새로운 재조정 엔진이다. 한국어로는 리액트 파이버라고 읽는다.
V-DOM은 상태가 바뀌면 가상 트리를 비교(Diffing)하고, 변경분만 native DOM에 재조정(Reconciliation) 하는 패턴이었다. 그래서 V-DOM에서 재조정은 필수적인 작업인데, 이를 좀 더 효율적으로 그리고 스케줄링이 가능하도록 하기 위해서 나온 것이 Fiber이다.
React 공식 문서에는 Fiber에 대한 내용이 담겨있지 않다. React Core 팀의 Andrew Clark이 작성한 글에서 소개한 내용이 거의 공식 문서를 대체하고 있으니, react-fiber-architecture을 참고하자.
[React Fiber의 목표]
- 증분 렌더링 (Incremental Rendering): 렌더링 작업을 작은 단위(청크)로 분할하고 이를 여러 프레임에 걸쳐 분산해 대규모 UI 업데이트 시에도 단일 작업이 16ms를 초과하지 않도록 제어하여, 화면 끊김(프레임 드롭) 현상을 방지한다.
- 작업의 일시 중지 및 재개: 진행 중인 작업을 일시적으로 멈추고, 나중에 다시 돌아와서 작업을 재개할 수 있도록 한다.
- 작업 우선순위 부여: 다양한 유형의 업데이트 작업에 각각 다른 우선순위를 할당한다. 만약 기존 작업 중에 더 우선순위가 높은 작업이 인입될 경우, 진행 중이던 작업을 멈추고 새로운 작업을 먼저 처리할 수 있다.
- 작업의 재사용: 이전에 완료된 작업을 재사용하여 불필요한 추가 연산을 줄인다.
- 불필요한 작업 중단: 새로운 업데이트가 들어오면서 기존의 렌더링 작업이 더 이상 필요 없어지면, 해당 작업을 완전히 중단(취소)한다.
Stack Reconciler의 한계
React 15까지 사용된 기존 엔진을 Stack Reconciler라 부른다. 이름처럼 콜 스택 기반으로 동작했다. 트리 비교를 시작하면 끝날 때까지 멈출 수 없었다.
상태 변경 → Diffing 시작 → ... (트리가 크면 수백 ms) ... → DOM 반영 → 완료
↑ 이 구간 동안 메인 스레드 블로킹자바스크립트는 싱글 스레드다. Reconciliation이 메인 스레드를 오래 점유하면, 그 사이에 사용자 입력, 애니메이션, 스크롤 같은 작업이 전부 멈춘다. 트리가 작을 때는 문제없지만, 복잡한 UI에서는 눈에 보이는 버벅임(jank)이 발생했다.
요리사 한 명이 10인분 코스 요리를 순서대로 만들고 있는데, 중간에 "물 한 잔만 주세요"라는 요청이 와도 코스가 끝날 때까지 무시하는 것과 같다.
Fiber의 핵심 아이디어
React 16에서 도입된 Fiber는 이 문제를 해결하기 위해 Reconciliation 엔진을 완전히 새로 설계한 것이다.
가장 핵심적인 아이디어는 두 가지다.
1. 작업을 쪼갠다 (증분 렌더링, Incremental Rendering)
기존에는 트리 전체를 한 번에 처리했다면, Fiber는 작업을 fiber라는 작은 단위로 쪼갠다. 각 fiber는 컴포넌트 하나에 대응하는 객체로, 트리의 노드 역할을 한다.
# Stack Reconciler
[====================================] 한 번에 처리
# Fiber
[====] [====] [====] [====] [====] 쪼개서 처리
↑ 여기서 잠시 멈추고 급한 일 먼저 처리 가능2. 우선순위를 매긴다 (작업 우선순위 부여, Priority Scheduling)
모든 업데이트가 동등하지 않다. Fiber는 작업에 우선순위를 부여한다.
| 우선순위 | 예시 | 처리 |
|---|---|---|
| 높음 | 사용자 입력, 클릭, 키보드 | 즉시 처리 |
| 보통 | 데이터 패칭 결과 반영 | 다음 프레임에 처리 |
| 낮음 | 화면 밖 요소 렌더링 | 여유 있을 때 처리 |
덕분에 무거운 렌더링 작업 중에도 사용자 입력에 즉시 반응할 수 있다.
아까 그 요리사가 이제는 요리 단계마다 잠깐 멈추고, "혹시 급한 주문 있나?" 확인할 수 있게 된 셈이다.
Fiber의 두 단계
Fiber는 작업을 Render Phase와 Commit Phase, 두 단계로 나눈다.
Render Phase (중단 가능)
- 새로운 fiber 트리를 만들고, 이전 트리와 비교(Diffing)한다.
- 이 단계는 메모리에서만 일어나기 때문에, 중간에 멈췄다 다시 시작할 수 있다.
- 더 급한 작업이 들어오면 현재 작업을 중단하고 우선 처리한다.
Commit Phase (중단 불가)
- Render Phase에서 계산된 변경 사항을 native DOM에 반영한다.
- 사용자에게 보이는 화면을 바꾸는 작업이므로, 한 번 시작하면 끝까지 실행된다.
[Render Phase] [Commit Phase]
fiber 트리 생성 → Diffing native DOM 반영
(중단 가능, 우선순위 스케줄링) (중단 불가, 동기 실행)Double Buffering
Fiber는 트리를 항상 두 개 유지한다.
- current 트리: 현재 화면에 반영된 상태
- workInProgress 트리: 다음 상태를 준비 중인 트리
Render Phase에서 workInProgress 트리를 완성하고, Commit Phase에서 이 트리를 current로 교체한다.
이 방식을 Double Buffering이라 부른다. 게임이나 영상에서 화면 깜빡임을 방지하기 위해 쓰는 기법과 같은 원리다.
정리
| 구분 | Stack Reconciler (React 15) | Fiber (React 16+) |
|---|---|---|
| 작업 단위 | 트리 전체 | fiber (컴포넌트 단위) |
| 중단 가능 | 불가 | 가능 (Render Phase) |
| 우선순위 | 없음 | 있음 |
| 스케줄링 | 동기 | 비동기 (Concurrent) |
Fiber의 등장으로 React는 단순한 Virtual DOM 라이브러리를 넘어, Concurrent Rendering이라는 새로운 패러다임을 열 수 있게 됐다.
useTransition, Suspense 같은 기능도 모두 Fiber 아키텍처 위에서 동작한다.