리액트 개발자로서 "리액트는 빠르다"라는 말을 자주 듣습니다. 하지만 왜, 어떻게 빠른지 깊이 있게 이해하는 것은 시니어 개발자로 가는 첫걸음입니다. 리액트의 핵심 엔진이라 할 수 있는 재조정(Reconciliation) 알고리즘을 파헤쳐 보겠습니다.
1. 가상 DOM(Virtual DOM)은 왜 필요한가?
브라우저의 실제 DOM을 조작하는 비용은 매우 비쌉니다. 요소 하나가 바뀔 때마다 브라우저는 레이아웃을 다시 계산하고(Reflow), 화면을 다시 그리는(Repaint) 복잡한 과정을 거치기 때문입니다.
리액트는 이 문제를 가상 DOM이라는 개념으로 해결합니다.
- 메모리 상의 복사본: 실제 DOM에 반영하기 전, 메모리에 가벼운 객체 형태로 DOM 트리를 먼저 만듭니다.
- 일괄 업데이트 (Batching): 변화가 생기면 가상 DOM에서 먼저 계산한 뒤, **최종적인 차이점(Diff)**만 실제 DOM에 딱 한 번 적용합니다.
2. 재조정(Reconciliation): 비교 알고리즘의 마법
두 개의 트리를 비교하여 변경된 부분을 찾는 알고리즘의 일반적인 시간 복잡도는 $O(n^3)$입니다. 노드가 1,000개만 되어도 10억 번의 비교가 필요하죠. 리액트는 이를 해결하기 위해 두 가지 **휴리스틱(Heuristic)**을 사용하여 복잡도를 **$O(n)$**으로 획기적으로 낮췄습니다.
2-1. 규칙 1: 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만든다
리액트는 두 엘리먼트의 루트 타입이 다르면(예: <div>가 <span>으로 바뀜), 이전 트리를 완전히 버리고 새로운 트리를 구축합니다.
- 이 과정에서 이전 컴포넌트는 완전히 파괴(unmount)되고, 상태(state)도 함께 사라집니다.
2-2. 규칙 2: Key를 통해 엘리먼트의 변하지 않는 정체성을 확인한다
가장 중요한 부분입니다. 리액트는 자식 노드들을 비교할 때 key 속성을 사용해 기존 트리와 새 트리의 자식들이 일치하는지 확인합니다.
3. 왜 key에 인덱스(index)를 쓰면 안 될까요?
리스트를 렌더링할 때 배열의 인덱스를 key로 사용하면 성능 저하나 예기치 못한 버그가 발생할 수 있습니다.
- 문제 상황: 배열의 맨 앞에 새로운 아이템이 추가되면, 나머지 모든 아이템의 인덱스가 하나씩 밀립니다.
- 리액트의 오해: 리액트는 key 값이 바뀌었으므로 모든 데이터가 변했다고 착각하여 실제 DOM을 전부 다시 그립니다.
- 결과: 단순 추가임에도 불구하고 전체 리스트를 재렌더링하게 되어 성능이 낭비되고, 입력 폼(input) 같은 상태가 엉뚱한 곳에 남는 버그가 생깁니다.
💡 시니어의 조언: key는 반드시 형제 요소 사이에서 고유하고 변하지 않는 ID(예: 데이터베이스의 id)를 사용해야 합니다.
4. React Fiber: 더 부드러운 UI를 위한 엔진
과거의 리액트 재조정 엔진(Stack Reconciler)은 동기적으로 작동했습니다. 즉, 작업이 시작되면 끝날 때까지 메인 스레드를 점유하여 화면이 버벅이는 현상이 있었죠.
이를 해결하기 위해 도입된 것이 React Fiber입니다.
- 작업의 분할: 렌더링 작업을 작은 단위(Fiber)로 쪼개어 여러 프레임에 걸쳐 수행합니다.
- 우선순위 제어: 사용자 입력이나 애니메이션처럼 중요한 작업이 들어오면, 진행 중이던 렌더링을 잠시 멈추고 중요한 일을 먼저 처리합니다. [Image showing incremental rendering concept in React Fiber]
'개발 > React' 카테고리의 다른 글
| [고급반] Step 1-3. 대용량 데이터 렌더링: Windowing 기법으로 1만 개 리스트 다루기 (0) | 2025.12.23 |
|---|---|
| [고급반] Step 1-2. Memoization 전략: memo, useMemo, useCallback의 명과 암 (0) | 2025.12.23 |
| [중급반] Step 3-3. 비동기 통신 및 에러 처리 고급 기법 (0) | 2025.12.15 |
| [중급반] Step 3-2. GraphQL 연동 심화 (REST API의 대안) (0) | 2025.12.15 |
| [중급반] Step 3-1. 서버 상태 관리 라이브러리 (React Query / SWR) (0) | 2025.12.15 |