React 첫 렌더링이 되는 과정 정리와 의문

HANITZ·2024년 1월 17일
0

React

목록 보기
5/8
post-thumbnail

리액트 초기 렌더링을 직접 디버깅하면서 과정들을 적어봤다.

과정들이 생각보다 복잡한 것같아서 핵심 로직들만 따로 정리해보고자 한다.

Reconciler, Scheduler

리액트는 크게 reconciler와 scheduler로 구분되어 렌더링이 진행된다.

reconciler는 VDOM에 관한 모든 것과 렌더링 작업을 담당하는 역할이고

scheduler는 이런 렌더링 작업이 언제 실행이 되어야하는지 정해주는 역할로 구분한다.


우선 reconciler에서 기본적인 fiberRoot와 Lane이 기록된 노드를 만들어준다.

그 후, scheduler에 performConcurrentOnRoot를 넘겨주면서 scheduler로 이동한다.

scheduler에서 들어온 update를 task에 추가한다.

작업 진행여부를 판단해 MessageChannel을 통해 메세지를 보낸다.

message를 받으면서 콜백함수인 performWorkOnRoot함수를 실행한다.

이때, workLoop로 모든 task를 처리하는데 처리할 때마다 reconciler에서 넘겨줬던 performConcurrentWorkOnRoot를 실행하기 때문에 다시 reconciler영역으로 넘어온다.

performUnitOfWork에서 root부터 시작해 VDOM 렌더링을 하는데 자식 > 형제 > 부모 순서로 탐색이 진행된다. 모든 트리를 탐색하고 다시 root로 돌아오면 render phase가 종료된다.

commitRoot로 commit phase가 시작된다. commit phase는 모든 작업이 끝날 때까지 멈추지 않고 작동된다.


후기 및 의문점

코드가 복잡해서 이해하기 쉽지 않았지만 역할 단위로 정리해서 보니까 보다 쉽게 이해할 수 있었다.

그런데 scheduler에서 Message Channel로 렌더링 실행 함수를 보내는 것은 쉽게 이해되지 않았다.

뭔가 렌더함수가 가상돔을 그리는 작업이기 때문에 다른 함수들보다 무겁기 때문에 작업순서를 뒤로 보내기위해 실행한 것이란 생각은 했지만, 내부 비동기 함수를 사용하지 않고 Message Channel을 사용한 이유가 의문이다...

https://github.com/facebook/react/pull/20834

비동기 함수로 setTimeout 대신 Message Channel을 사용하는 이유에 대해서 알아봤다.

  1. 4ms 클램핑: setTimeout은 4ms의 최소 지연시간이 있다고 한다. 하지만 Message Channel은 지연시간 없이 즉각적으로 실행이 가능하기때문에 MessageChannel을 사용한다.

  2. 이런 작업이 가능한 이유는 setTimeout은 MacroTask에서 실행되고 Message Channel은 MicroTask가 실행되기 때문이다.

  3. Node.js에 setImmediate라는 대체 함수가 있었지만 Nodejs에서만 작동한다는 점과 setTimeout과 마찬가지로 MacroTask에서 실행되다는 점이 문제였다.
    반면 Message Channel은 모든 주요 브라우저에서 지원되는 웹표준 API이기 때문에 호환성면에서 더 우수하기때문이다.


reference

React 18 톺아보기 - 04. Concurrent Render

Inside React

0개의 댓글

관련 채용 정보