본문으로 이동

Mini React

Virtual DOM과 Hooks를 직접 구현하고, 동기식 렌더링을 작업 단위로 나누는 Fiber Reconciler와 협력형 스케줄러로 확장한 JavaScript 런타임

상태가 바뀌어도 현재 화면은 유지하고, 작업 중인 Fiber 트리가 완성된 뒤에만 DOM을 변경합니다.
실행 환경
Vanilla JavaScript · DOM
핵심 구조
Virtual DOM · Diff & Patch → Fiber
검증
83 tests passed

프로젝트 요약

담당 역할 및 기여

  • Virtual DOM·Diff/Patch·Hooks의 실행 흐름 구현
  • Fiber Reconciler와 협력형 스케줄러 설계 및 검증

핵심 구현

  • Render·Commit 분리와 오래된 비동기 렌더 취소
  • key 기반 DOM 재사용과 작업 중단·재개 구현

한 번에 처리하던 렌더링을 작은 작업 단위로 분리

상태 변경이 화면에 반영되는 과정을 이해하기 위해 Virtual DOM과 Hooks를 직접 구현했습니다. 초기 Diff/Patch 엔진은 전체 트리를 재귀적으로 비교해 한 번에 반영하는 구조여서, 계산 도중 브라우저에 제어권을 돌려주거나 새로운 렌더 요청으로 교체하기 어려웠습니다.

이를 해결하기 위해 트리 순회를 Fiber 단위로 나누고, 변경 사항을 계산하는 Render와 실제 DOM을 바꾸는 Commit을 분리했습니다.

BEFORE · SYNC VDOM전체 트리를 한 번에 처리
  • 재귀 호출로 전체 트리 비교
  • 계산 중간에 중단·재개 불가
  • Diff 직후 DOM에 변경 반영
AFTER · FIBER작업을 나누고 완성된 결과만 반영
  • Fiber 단위로 다음 작업 추적
  • 작업 양보·재개·취소 가능
  • Render 완료 후 Commit

Current · WIP Fiber

현재 화면의 Current 트리는 유지하고, 다음 화면은 Work-in-Progress 트리에서 계산합니다. parent·child·sibling으로 다음 작업을 찾고, alternate로 이전 Fiber를 연결해 DOM을 재사용합니다.

parentchildsiblingalternate
각 Fiber는 부모·첫 자식·다음 형제·이전 트리를 가리키며, 재귀 호출 스택 없이 다음 작업을 찾습니다.

브라우저에 제어권을 양보하고, 최신 요청만 화면에 반영

patchAsync()는 requestIdleCallback과 timeout fallback을 사용해 렌더 작업을 여러 구간으로 나눕니다. 실행을 멈춘 위치를 저장하고 다음 구간에서 이어가며, 새 요청이 들어오면 아직 Commit하지 않은 이전 작업을 취소합니다. 기존 patch()는 같은 Fiber 작업을 한 번에 끝내도록 해 동기 동작을 유지했습니다.

patchAsync()는 브라우저에 제어권을 돌려주며 Render를 이어가고, Commit은 완성된 결과를 한 번에 반영합니다.

계산 중에는 현재 화면을 유지하고, 끝까지 완성된 작업의 변경 사항만 DOM에 반영하도록 했습니다.

Hooks · 업데이트를 묶는 시점

Microtask batching으로 여러 setState 요청을 하나의 업데이트로 묶습니다.

Scheduler · 렌더 작업을 나누는 방식

시작된 렌더를 작은 작업으로 나누고, 브라우저에 제어권을 돌려준 뒤 이어서 처리합니다.

리스트 순서가 바뀌어도 기존 DOM을 재사용

Keyed Reconciliation에서는 같은 key와 type을 가진 항목을 동일한 노드로 판단합니다. 이전 Fiber와 DOM을 재사용하고, 위치가 달라진 노드에는 MOVE Effect를 기록해 새로 생성하지 않고 이동으로 처리했습니다.

같은 key와 type은 동일한 노드로 판단합니다. 순서만 바뀌면 새로 생성하지 않고 기존 DOM을 이동합니다.

목록의 순서 변경과 노드의 생성·삭제를 구분해 필요한 DOM 변경만 반영했습니다.

83개의 테스트로 실행 흐름과 DOM 반영 시점을 검증

기존 Hooks·Diff/Patch·History 테스트에 Fiber 시나리오를 추가해 전체 83개의 테스트를 통과했습니다. 최종 화면뿐 아니라, 계산 중 DOM 유지와 작업 취소·재개 과정도 확인했습니다.

주요 검증 시나리오
검증 항목확인한 동작
Fiber 연결부모·자식·형제와 이전 Fiber의 연결을 유지
Render / Commit계산이 완료되기 전에는 실제 DOM을 변경하지 않음
Yield / Resume중단한 위치를 보존하고 다음 작업 구간에서 재개
Key 기반 이동리스트 순서가 바뀌어도 기존 DOM 노드를 재사용
오래된 작업 취소이전 비동기 렌더를 취소하고 최신 작업만 Commit
  • JavaScript
  • Virtual DOM
  • Hooks
  • Fiber
  • Keyed Reconciliation
  • Render / Commit
  • Cooperative Scheduler