본문 바로가기

TIL

[React 까보기 시리즈] 리액트가 브라우저에게 메인 쓰레드를 양보할 타이밍을 아는 방법(isInputPending API)

리액트는 브라우저에게 언제 양보할지 어떻게 알까? 

 

양보해야 하는 배경 

크롬 브라우저는 멀티 프로세스 구조 그 중 렌더러(Renderer) 프로세스에는 메인쓰레드가 있음. 

메인 쓰레드에서는 Html 파싱, 자바스크립트 실행, 렌더 트리 구축, 페인트 작업까지 모두 담당 

자바스크립트 실행을 하는 중에는 그 외에 다른 작업 불가능 

리액트 렌더링 연산 과정이 복잡해지면 끝날 때까지 사용자 이벤트 처리나 페인트가 blocking! 

deview 2021 blocking 발표에 예시가 있음 

 

열쇠 : isInputPending 

페이스북 기여한 브라우저 API. 사용자 input이 있는지(pending) javascript에서 알 수 있는 API 

리액트는 특정 주기로 콜스택을 비워주었음 -> 메인 쓰레드를 양보하는 타이밍을 모르기 때문에 isInputPending이 있으면 양보하는 타이밍을 알게 됨(true일 때) 

 

방법 : shouldYieldToHost 

isInputPending 지원 

사용자 이벤트와 페인트 두가지 각각 따로 알 수 있음. 이 외에는 리액트는 WORK를 처리(렌더링 진행) 

- isInputPending(사용자 이벤트) : API 

- needsPaing(페인트)  : VDOM이 DOM에 반영 완료된 후, reconciler가 needsPaint= true 

 

isInputPending 미지원 

주기적으로 (deadling) 콜스택 (메인 쓰레드) 비워줘야 함 -> 따라서 needsPaint도 필요없음 (어짜피 비움) 

 

fps에 따라서 deadline이 달라짐 -> forceFrameRAte 함수 제공 (yieldInterval 조절 함수) 

 

사용처 

- workLoop : scheduler 안에서 즉, commit phase의 진행 우선순위 변경

- unstable_showYield: reconciler에게 양보 여부 알려주기 위한 함수 즉 render pharse의 진행 우선순위 변경 -> reconciler에서 workLoopConcurrent 

 

unstable_showYield 함수 

taskQueue에 firstTask 가  currentTask보다 우선순위가 높다면? 또는 shouldYieldToHostrk true -> render phase 중지 

 

 

 

 

Event loop와 callstack 어떻게 동작하나? 

JS 엔진 (기계어로 바꿔서 컴퓨터가 실행할 수 있도록 해줌) - memory heap, call stack 

 

싱글쓰레드 : call stack이 하나다 

event loop -> callstack 이 비워지면 callback queue를 callstack으로 옮겨줌 

call stack -> 안에 있는 것 실행 

 

Browswer rendering process 

 

dom 트리 구축 위한 html 파싱 -> 렌더 트리 구축 -> 렌더 트리 배치 -> 렌더 트리 그리기 

 

webkit 동작 과정 

1. html을 parsing하여 dom tree 생성 

2. css (style sheets)를 parsing하여 스타일 규칙 얻는다 

3. dom tree를 생성하는 동시에 이미 생성된 dom tree와 스타일 규칙(cssom)을 attachment한다. 

4. 구축한 render tree를 배치(layout) 한다 

5.  배치가 끝난 render tree를 그린다