Fiber가 중요한 작업 먼저 처리하고 나머지는 뒤로 미루는 전략을 사용하는 것을 보면서, 개발자는 UI 흐름에서 어떤 부분이 사용자에게 더 중요한지 판단하고 그 맥락을 코드 구조에 반영해야 한다는 점을 깨달았습니다.
React의 최신 기능들(Concurrent Mode, Suspense, Server Components)은 모두 Fiber 엔진 위에서 작동하고 있기 때문에, Fiber 아키텍처를 중심으로 React 내부 구조를 계속 학습하는 것은 진화하는 React 생태계에서 꼭 알아야할 필수적인 개념이라고 생각합니다. 찾아볼수록 어렵다고 느껴져 끊임없이 공부하며 글을 개선해보겠습니다 :)
React를 사용하는 대다수의 개발자는 JSX → Virtual DOM → Reconciliation → DOM 업데이트의 흐름을 기본으로 알고 있겠지만 React 16부터 도입된 Fiber 아키텍처는 이 흐름의 내부 엔진을 완전히 재설계한 방법입니다. 이 방법으로 React의 근본적인 동작 방식과 성능 최적화에 어떤 변화를 가져왔는지 더 깊이 이해하는 시간을 가져보겠습니다.
1. 왜 Fiber가 등장했을까?
React의 이전 버전(React 15 이전)은 스택 기반 Reconciler를 사용했습니다. 이 방식은 업데이트가 발생하면 트리를 재귀적으로 순회하며 모든 작업을 동기적으로 수행하는 방법입니다. 하지만 복잡한 UI나 대규모 상태 변화가 있을 때, 렌더링 작업이 길어지면 브라우저의 메인 스레드를 장시간 점유하게 된다는 단점이 있었습니다.
브라우저는 일반적으로 1초에 60프레임(약 16ms당 1프레임)을 목표로 부드러운 애니메이션을 제공해야 합니다. 하지만 렌더링 작업이 이 16ms를 넘어서 길어지면, 클릭이나 타이핑 등 사용자 입력 처리나 애니메이션 업데이트가 지연되어 프레임 드롭이 발생하고 UI가 버벅거리는 문제가 생겼습니다.
React 팀이 이 문제를 해결하기 위해 렌더링 작업을 작은 단위로 쪼개어서 처리하고, 우선순위를 두어 중요한 작업(사용자 입력 등)을 먼저 처리할 수 있는 새로운 엔진이 필요하다고 판단해 도입된 것이 바로 Fiber 아키텍처입니다. 즉, Fiber는 React의 Reconciler를 재구성한 비동기 스케줄링 기반 엔진입니다.
2. Fiber 아키텍처란? 특징과 개념 이해하기
Fiber는 React가 렌더링 작업을 수행하는 방식을 근본적으로 바꾼 새로운 Reconciler입니다. 이해하기 쉬운 개념은 아니기에 개념을 따로 정리해보았습니다.
📍 핵심 개념
| 개념 | 설명 |
| Fiber (작업 단위) | React 요소, 상태, props, 부모-자식 관계 등 작업에 필요한 모든 정보를 담는 내부 작업 단위 객체입니다. 각 컴포넌트 인스턴스에 대응하는 메모리상의 데이터 구조입니다. |
| Fiber Tree | Fiber 노드들은 child, sibling, return(부모) 포인터를 통해 연결되어, 연결 리스트(Linked List) 형태로 트리를 구성합니다. 이는 재귀 대신 반복적인 순회를 가능하게 합니다. |
| Current / Work-In-Progress Tree | UI에 현재 반영된 Fiber 트리(Current)와 업데이트를 준비 중인 미리 구성된 Fiber 트리(Work-In-Progress)를 번갈아 사용합니다. 계산 중인 Work-In-Progress는 언제든 중단될 수 있습니다. |
| 타임 슬라이싱 (Time Slicing) | 긴 렌더링 작업을 여러 프레임에 나눠서 처리하는 방식입니다. 브라우저가 남은 여유 시간이 있을 때만 작업을 수행하여, 메인 스레드를 오랫동안 독점하지 않게 합니다. |
| 스케줄러 & 우선순위 | 각 업데이트 작업에 우선순위(ex: 사용자 입력 > 애니메이션 > 데이터 Fetch)를 부여하여, 중요한 작업을 먼저 처리할 수 있도록 작업 순서를 조절합니다. |
| 렌더링 / 커밋 단계 | 렌더링 단계는 중단 및 재시작이 가능하며(비동기), 변경 사항을 계산합니다. 커밋 단계는 DOM에 실제 반영하는 단계로, 항상 동기적으로 이루어지며 중단되지 않습니다. |
Fiber의 가장 중요한 특징: 중단 가능성 (Interruptible Work)
Fiber가 스택 기반 리컨실러와 구별되는 가장 핵심적인 특징은 렌더링 작업이 중단될 수 있다는 것입니다.
작업은 작은 단위(Fiber)로 쪼개져 처리되며, 각 단위 작업이 끝날 때마다 React는 더 중요한 할 일이 있는지 확인합니다. 만약 더 급한 작업이 있다면, 현재 렌더링 작업을 멈추고 중요한 작업을 먼저 처리합니다.
| 특징 | 설명 |
| 중단 가능성 | 렌더링 작업 중간에 중단하고 더 급한 작업을 처리할 수 있음. |
| 우선순위 처리 | 여러 작업이 동시에 있을 때 중요도에 따라 순서를 조절. |
| 점진적 렌더링 | 전체 렌더링을 한 번에 하지 않고 여러 조각으로 나눠 처리. |
3. 실사용 예시: Concurrent Mode와 useTransition
Fiber의 능력이 개발자에게 직접적으로 드러나는 것이 바로 React 18에서 도입된 Concurrent Mode API입니다. 이 API들은 내부적으로 Fiber의 스케줄링 기능을 활용합니다.
1) 일반적인 State 업데이트 (Blocking)
아래 코드는 Blocking 모드의 예시로, setFilter가 실행되면 필터링된 대량의 데이터(BigList)를 렌더링하는 작업이 완료될 때까지 UI가 차단(Block)됩니다. 따라서 사용자는 타이핑 중 UI가 잠깐 멈추는 것을 느낄 수 있습니다.
// 1. 일반적인 상태 업데이트 (Blocking)
function SearchableList() {
const [filter, setFilter] = useState('');
const filteredData = filterData(filter, data); // 오래 걸리는 계산
const handleInputChange = (e) => {
// ✋ 이 시점에 모든 업데이트가 동기적으로 처리됩니다.
setFilter(e.target.value);
};
return (
<>
<input type="text" value={filter} onChange={handleInputChange} />
<BigList data={filteredData} />
</>
);
}
2) Concurrent Mode와 useTransition 사용 (Non-Blocking)
useTransition 훅을 사용하면 업데이트를 긴급한 상태(Urgent)와 전환 상태(Transition)로 구분할 수 있습니다.
// 2. useTransition을 사용한 동시성 업데이트
import { useState, useTransition } from 'react';
function SearchableList() {
const [filter, setFilter] = useState(''); // 긴급한 상태 (입력 필드)
const [isPending, startTransition] = useTransition(); // 전환 상태 관리
const handleInputChange = (e) => {
// 1. ⚡️ 긴급 업데이트: Input 필드 상태는 즉시 업데이트
setFilter(e.target.value);
// 2. 🐢 전환 업데이트: BigList 렌더링은 전환으로 처리
startTransition(() => {
// 이 내부의 상태 업데이트는 Fiber 스케줄러에 의해 우선순위가 낮게 처리됩니다.
setDeferredFilter(e.target.value);
});
};
return (
<>
<input type="text" value={filter} onChange={handleInputChange} />
{isPending && <div>로딩 중...</div>}
{/* 긴급하게 반응하는 filter 대신, 지연된 filter를 사용 */}
<BigList data={filterData(deferredFilter, data)} />
</>
);
}
Fiber의 역할:
- 사용자가 입력할 때 setFilter (Input 업데이트)는 높은 우선순위로 즉시 처리됩니다. (UI 반응성 확보)
- startTransition 내부의 setDeferredFilter (목록 갱신)는 낮은 우선순위로 스케줄링됩니다.
- 만약 목록을 렌더링하는 도중 사용자가 추가로 타이핑하면, Fiber는 목록 갱신 작업을 중단하고 새 타이핑을 먼저 처리합니다.
- 새로운 타이핑 작업이 완료된 후, 목록 갱신 작업을 재개합니다.
이러한 타임 슬라이싱 덕분에, 대규모 데이터 렌더링 중에도 사용자 입력 필드와 애니메이션은 멈추지 않고 부드럽게 작동합니다.
4. 회고
Fiber가 중요한 작업 먼저 처리하고 나머지는 뒤로 미루는 전략을 사용하는 것을 보면서, 개발자는 UI 흐름에서 어떤 부분이 사용자에게 더 중요한지 판단하고 그 맥락을 코드 구조에 반영해야 한다는 점을 깨달았습니다.
React의 최신 기능들(Concurrent Mode, Suspense, Server Components)은 모두 Fiber 엔진 위에서 작동하고 있기 때문에, Fiber 아키텍처를 중심으로 React 내부 구조를 계속 학습하는 것은 진화하는 React 생태계에서 꼭 알아야할 필수적인 개념이라고 생각합니다. 찾아볼수록 어렵다고 느껴져 끊임없이 공부하며 글을 개선해보겠습니다 :)
'📚 CS > React' 카테고리의 다른 글
| [React] Props Drilling이란? (0) | 2025.10.06 |
|---|---|
| [React] useRef 알아보기 (0) | 2025.09.16 |
| [React] useEffect, useLayoutEffect 비교하기 (0) | 2025.09.14 |
| [React] 클래스형 컴포넌트 vs 함수형 컴포넌트 (0) | 2025.09.12 |
| [React] React Hooks: 함수형 컴포넌트 알아보기 (0) | 2025.09.11 |