Fiber 아키텍처는 React 16에 도입된 새로운 렌더링 엔진으로, 복잡한 상태 변화와 상호작용에도 매끄럽게 대응할 수 있도록 하는 것입니다. Fiber 아키텍처의 개념과 역할, React의 상태 관리와의 관계, 상태 관리 라이브러리와는 어떻게 통합될 수 있을지 알아보았습니다.
- 기존 React(16 이전) 은 동기식 스택 기반으로 전체 컴포넌트를 한 번에 렌더링함
- 프레임 드랍과 메인 스레드 점유문제 발생
- 브라우저는 초당 60프레임의 속도로 UI를 업데이트
- 메인 스레드는 DOM 업데이트, JavaScript 실행, 스타일 계산 등 많은 작업을 동시에 수행
- 프레임당 약 16ms의 시간 내에 모든 작업을 완료해야 프레임 드랍이 발생하지 않음
프레임 드랍 ?
- 연속된 장면 중 하나의 화면을 '프레임' 이라고 함
- 모니터 주사율이 60fps(Frame Per Second, 초당 표시되는 프레임 수) 라고 하면 1초 동안 60장의 정지 화면이 이어져 자연스러운 움직임을 제공할 수 있음
- 성능 문제로 이 시간을 초과하면 화면이 끊기는 현상이 생기는데 이를 프레임 드랍이라고 함
- 긴 작업이 메인 스레드를 장시간 점유하면 사용자 입력이 지연된다거나 하는 등 UX 가 안좋아짐
- 작업을 중간에 멈추거나 다른 작업을 우선 처리할 수 없음
- 애니메이션과 같은 UI 상호작용 요소는 다른 작업보다 최우선으로 렌더링되어야 자연스러움
- 프레임 드랍과 메인 스레드 점유문제 발생
=> 프레임 드랍, 메인 스레드 점유 문제를 해결하고 작업에 우선순위을 설정하여 처리하기 위해 비동기적이고 우선순위 기반의 Fiber 아키텍처가 도입됨.
- React 컴포넌트 구조와 상태를 LCRS 트리 형태로 표현한 구조
- Reconciliation 과정에서 변경 사항 추적
- 변경사항을 적용하기 위해 Reconciliation 과정에서 이중 버퍼링(Double Buffering) 방식 사용
- 현재 화면에 렌더링 실제 DOM 트리인 current tree
- 변경사항을 반영하기 위해 작업 중인 workInProgress tree : reconciliation 과정에서 비교 및 업데이트를 거쳐 최종적으로 current tree에 반영
export type Fiber = {
// Fiber의 유형을 식별하는 태그
// 숫자의 union type - 0번이 functional component, 1번이 class component
tag: WorkTag,
// 자식 들의 고유한 식별자
key: null | string,
// element의 타입을 넣어주는 값
elementType: any,
// 이 fiber와 관련된 이미 계산된 function, class 정보
type: any,
// 이 fiber와 관련된 local state 정보
stateNode: any,
// 부모 fiber 노드
return: Fiber | null,
// Linked List 트리 구조를 만들기 위해 설계된 구조
// 자기 자식(child)에 관련된 정보, 형제(sibling) 정보
child: Fiber | null,
sibling: Fiber | null,
index: number,
// 실제 DOM 노드나 class 인스턴스에 접근하기 위해 필요한 정보
ref:
| null
| (((handle: mixed) => void) & {_stringRef: ?string, ...})
| RefObject,
// 실제 출력 값을 위해 사용되는 state 정보
// useState, useRef, useMemo, useEffect 등의 hook에서 사용
memoizedState: any,
// Scheduler와 함께 동작하여, Fiber가 렌더링 작업을 우선순위에 따라 조정할 수 있게 함
lanes: Lanes,
childLanes: Lanes,
// 현재 작업 중인 Fiber 노드와 기존에 렌더링된 Fiber 노드 간의 연결을 나타내는 속성
alternate: Fiber | null,
};
- 각 컴포넌트를
Fiber
노드로 관리 Fiber
란 수행해야하거나, 이미 수행한 컴포넌트의 작업 단위- 컴포넌트의
state
,props
,DOM
등의 정보 저장go 변경이 발생했을 때 이전 상태와 비교할 수 있는 정보를 제공 - 컴포넌트 내에 사용된 모든 훅을 하나의 연결된 목록(
linked list
) 형태로 관리함memoizedState
속성이 훅 리스트의 시작 지점을 가리짐- 훅 상태가 업데이트되면 새로운 Fiber 객체가 생성되는 대신, 기존 Fiber 객체 내의 훅 상태 리스트만 업데이트해 불필요한 메모리 할당을 방지
- current 트리의 개별 노드와 작업 중인 workInProgress 트리의 해당 노드가 서로를
alternate
속성을 통해 참조해 변경 사항 추적해 비교할 수 있게 함 - 각 작업의 우선순위를 가지고 있음
lane
속성을 통해 작업의 우선순위를 관리- 이를 기반으로 Scheduler 가 작업 스케줄링
- Fiber는 React가 컴포넌트의 상태 변화에 따라 필요한 부분만 업데이트할 수 있도록 함
- Double Buffering 구조를 사용하여 current와 workInProgress 트리를 관리하고, Reconciliation 과정에서 두 트리를 비교
- 상태가 변경될 때마다 전체 트리를 다시 렌더링하지 않고, 변경된 부분만 찾아내어 업데이트
- 우선순위 기반 상태 업데이트
- 각 작업의 우선순위에 따라 중요한 상태 변화가 발생한 부분은 먼저 렌더링하고 덜 중요한 작업은 이후에 처리
- 사용자 입력과 같은 즉각적인 반응이 필요한 상태는 높은 우선순위를 부여받아 즉시 렌더링, 애니메이션이나 네트워크 요청에 따른 상태 변화는 낮은 우선순위로 설정되어 다른 작업 이후에 비동기적으로 처리됨
- 상태 변경에 따른 훅(hooks) 관리
- 컴포넌트의
state
와hooks
를 관리 - 상태가 변경되면 Fiber는 훅 리스트를 순회하여 필요한 상태만 업데이트함
- 컴포넌트의