Fiber

용어

Fiber Architecture

Fiber Node, Fiber Tree, FiberRoot, rootFiber

Fiber Reconciler는 Fiber Node 기반으로 실현


Vdom에 대한 이해?

  1. Fiber 객체 자체가 Vdom이다.
  2. 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>

참고