Fiber
용어
Fiber Architecture
Fiber Node, Fiber Tree, FiberRoot, rootFiber
Fiber Reconciler는 Fiber Node 기반으로 실현
Vdom에 대한 이해?
- Fiber 객체 자체가 Vdom이다.
- vitrual DOM은 React.createElement()로 return된 객체. fiber는 vdom 을 realdom으로 실현하는 일부분.
Fiber 아키텍처의 의미
fiber는 node단위를 한개 workUnit으로 비동기 이고 중단 가능한 업데이트를 실현(concurrent 모드, timeSlice실현.)
데이터 구조
// https://github.com/facebook/react/blob/16.8.6/packages/react-reconciler/src/ReactFiber.js
function FiberNode(tag: WorkTag, pendingProps: mixed, key: null | string, mode: TypeOfMode) {
this.tag = tag; // fiber 대응하는 컴포넌트 유형 Function/Class/Host
this.key = key;
this.elementType = null; // type이랑 동일 하지만 일부 제외(예: React.memo사용시 제외)
this.type = null; // FC=>함수자체, CC=>클래스, HostComponent=>tagName
this.stateNode = null;
// 다른 fiber 연결용
this.return = null;
this.child = null;
this.sibling = null;
this.index = 0; // fiber관련 dom insert할때 인덱스.
this.ref = null;
// update 관련된 상태 관련 정보 저장.
this.pendingProps = pendingProps;
this.memoizedProps = null;
this.updateQueue = null;
this.memoizedState = null;
this.dependencies = null;
this.mode = mode;
// 부작용에 대한 내용 저장.
this.effectTag = NoEffect;
this.nextEffect = null;
this.firstEffect = null;
this.lastEffect = null;
// 우선순위 관련 처리
this.lanes = NoLanes;
this.childLanes = NoLanes;
// 해당 fiber 업데이트시 연관된 작업의 fiber(workInProgressFiber => currentFiber)
this.alternate = null;
}
Fiber DoubleBuffer
예를들어 canvas에서 화면을 그릴때 매프레임마다 ctx.clearRect로 이전 화면을 지운다.
새로 그리는 화면 컴퓨팅 시간이 많이 필요할 경우 흰색 화면만 보여주는 경우(Flickering)가 있다.
해당문제를 해결하기 위해서 메모리(cpu, gpu)에서 다음화면을 그릴때 까지 이전화면을 보여주고 화면이 완성된 후에 ctx.clearRect로 이전화면을 지우고 새화면을 교체해준다.
이와같이 메모리에서 구성하고 바로 교체 해주는 방식을 DoubleBuffer라고 한다.
current fiber ⇒ workInProgress fiber(alternate)
Root
fiberRoot(변하지 않음.) > rootFiber > App > div
JSX to Fiber
JSX ⇒ BABEL ⇒ React.createElement ⇒ ReactElement ⇒ ReactDom.render ⇒ ReactDOM.legacyCreateRootFromDOMContainer ⇒ createFiberRoot
fiber 생성순서

*React 자식요소가 only textNode일 경우 별도 fiber생성 하지 않는다. (isDirectTextChild)
<div><!-- 1 -->
<header/><!-- 2 -->
<h1><!-- 3 -->
page Title<!-- 4 -->
<span></span><!-- 5 -->
</h1>
<input /><!-- 6 -->
</header>
<div>contents</div><!-- 7 -->
<footer><!-- 8 -->
<div><!-- 9 -->
<p>copyright</p><!-- 10 -->
<p>email: aa@bb.com</p><!-- 11 -->
</div>
<p>footer</p><!-- 12 -->
</footer>
</div>
참고