리액트 패키지를 까보면 또 여러가지 구성 요소들이 있다. 이와 함께 리액트의 코어인 VDOM에도 대해 알아보자.
컴포넌트 정의와 관련된 패키지다. 리액트 엘레먼트를 만드는 createElement
가 포함되어 있으니 핵심 그 자체다. 다른 패키지에 의존성이 아예 없고, 브라우저나 모바일 등 다양한 플랫폼에 사용 가능하다.
react-dom, react-native-renderer 등 호스트 렌더링 환경에 의존한다. 전에 짚고 넘어간적이 있었던 친군데, 호스트와 리액트를 연결해주는 역할을 한다. react-dom은 DOM 조작을 담당하는것이고, react-native-renderer는 리액트 네이티브에서의 렌더링을 책임진다. 추후에 더 배울 reconciler와 legacy-events 패키지에 의존성이 있다.
SyntheticEvent라는 이름의 내부적으로 개발된 이벤트 시스템이다. 기존 웹에도 event가 있는데, 이를 wrapping하여 추가적인 기능을 수행 가능케 한다.
앞에 useState를 공부할 때 봤듯이, task들이 비동기로 실행된다. 이를 실행하는 타이밍을 우선순위를 매겨주는게 스케쥴러다.
Fiber 아키텍처에서 VDOM 재조정을 담당하고, 컴포넌트를 호출해준다.
앞에서도 공부했지만 한번더 명확히 정리해보자. 컴포넌트를 호출하고, 리액트 element를 받아 VDOM을 재조정하는 작업까지가 렌더링이다. DOM이 재조정되는건 이후 커밋 페이즈에 실행된다.
컴포넌트가 JSX를 리턴하면 babel을 통해 react.createElement가 호출되고 여기서 리턴되는게 React element다. 공식 문서에 따르면 "나중에 React가 컴포넌트를 렌더링하도록 지시하는 설명서"와 비슷하다.
VDOM의 노드 객체다. React element가 DOM에 반영되려면 먼저 VDOM에 추가되어야 하고, 이를 위해서 확장된게 fiber다. Fiber는 컴포넌트의 상태, 라이프사이클과 훅을 관리한다.
사진 출처: 링크
Virtual DOM, 가상 돔이라고 한다. 레거시 공식 문서에 따르면 "UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념" 이다. 왜 가상이냐 하면, 실제로 돔을 조작하는것이 가상으로 관리하고 조작하는것 보다 비용이 더 크기 때문이다.
우선 VDOM은 더블 버퍼링 구조의 트리 형태고, fiber node로 구성되어 있다. 사진 좌측의 current 부분은 DOM에 마운트된 fiber들이고, 우측 workInProgress 부분은 render phase에서 작업중이며, commit phase를 지나면 최신 트리가 될 트리다. 이 부분은 current tree에서 자가복제되어 만들어진다.
function performUnitOfWork(unitOfWork: Fiber): void {
// The current, flushed, state of this fiber is the alternate. Ideally
// nothing should rely on this, but relying on it here means that we don't
// need an additional field on the work in progress.
const current = unitOfWork.alternate;
...
Current와 workInProgress의 파이버 노드들은 서로 alternate 값으로 참조한다. 위의 함수에서도 "The current, flushed, state of this fiber is the alternate"라 설명하며 참조하는것을 알 수 있다.
Fiber는 첫번째 자식만을 child로 참조한다. 위에서 보이듯 첫 자식만 child와 return 관계로 서로 참조되며, 나머지 자식들은 sibling으로 참조된다.
많이 본 사진이다. 렌더 페이즈와 커밋 페이즈 두개를 나눠서 분석해본다.
VDOM을 재조정 (reconciliation) 하는 단계라 보면 된다. 이 단계에서 element를 추가, 수정, 삭제해야 하는 work를 스케쥴러에 등록한다. Work는 reconciler가 컴포넌트의 변경을 DOM에 적용하기 위해 수행하는 일이다.
리액트 16버전에서 스택 아키텍처에서 파이버 아키텍처로 바뀌면서, reconciler가 렌더링중 abort, stop, restart를 실행하여 렌더링 우선순위를 변경할 수 있게 되었다.
재조정한 VDOM을 DOM에 적용하고, 라이프사이클을 실행하는 단계다. 일관성을 위해 동기적으로, 일괄적으로 처리되고, 리액트가 콜스택을 비우고 브라우저가 paint를 시작한다.
[React 까보기 시리즈] React 구성요소인 reconciler, renderer 등의 내부 패키지 & fiber, rendering 등의 용어 정의