리액트의 렌더링 프로세스
리액트의 렌더링은 브라우저에 필요한 DOM 트리를 만드는 과정을 의미한다. 리엑트는 이 렌더링 작업을 위한 자체적인 렌더링 프로세스가 있다.
1. 렌더링 트리거
컴포넌트의 렌더링이 일어나는 이유
1. 초기렌더링 - createRoot의 실행
- 대상 DOM 노드와 함께 createRoot를 호출한 다음 해당 컴포넌트로 render 메소드 호출
2. 리렌더링 - 상태 업데이트
- 렌더링된 이후 set함수를 통해 state를 변화시켜 추가적인 렌더링을 유발
- props가 변경되는 경우
- 컴포넌트의 Key props가 변경되는 경우
컴포넌트의 상태를 업데이트하면 자동으로 렌더링 대기열에 추가
state update -> triggers -> render
2. Render와 Commit (Rendering = Render phase + Commit phase)
JSX를 리액트 엘리먼트들로 바꾸거나 Diffing 연산을 하는 부분을 Render단계라고 한다. 컴포넌트를 렌더링한 후(리액트 엘리먼트를 만들고 난 후) React는 real DOM을 수정하는데, 이를 Commit 단계라고 한다.
- 초기 렌더링에서 리액트는 루트 컴포넌트를 호출
- 리액트 엘리먼트를 만들고(Render) 바로 Real DOM에 커밋(Commit)함
- 이후 리렌더링에서 리액트는 state 업데이트가 일어나 렌더링을 트리거한 컴포넌트를 호출
- 렌더링 전의 리액트 엘리먼트 트리와 이후의 리액트 엘리먼트 트리를 비교하여 최소한의 연산을 계산(Render)한 후에 Real DOM에 반영(Commit)
재귀적 단계: 업데이트된 컴포넌트가 다른 컴포넌트를 반환 -> React는 해당 컴포넌트를 렌더링 -> 해당 컴포넌트도 컴포넌트를 반환 -> 반환된 컴포넌트를 다음에 렌더링
-> 중첩 컴포넌트가 없고 React가 화면에 표시되어야 하는 내용을 정확히 알 때까지 반복
커밋 단계는 개발자가 조작할 수 없지만, 렌더 단계는 조작할 수 있으므로 잘 설계하는 것이 중요하다. 리액트 엘리먼트의 트리의 깊이가 깊어지고 노드들이 많아질수록 React.memo를 사용하여 하위 트리 렌더링을 막는 등의 최적화를 해줘야 한다.
cf)
Fiber
Fiber는 React에서 작업의 단위이며, JavaSrciprt 객체이다. React 16 버전부터 리액트 파이버를 추가함으로서 랜더링 프로세스 방식에 변화를 주었다.
기존 문제점: Stack Reconciler의 작동 방식은 동기적으로 이뤄졌으며 모든 작업을 스택으로 처리했다. (한번 작업이 시작되면 끝날때까지 멈추지 않았음)
-> 그래서 fiber 도입
1. Fiber의 주 역할
- 연산을 멈추고 다시 수행할 수 있는 기능
- 각기 역할마다 다른 우선순위를 부여할 수 있는 기능
- 이전에 완료된 연산을 재사용할 수 있는 기능
- 필요가 없어진 연산을 중간에 취소하는 기능
Stack Reconciler와 달리 Fiber Reconciler는 더 이상 재조정을 렌더링과 동시에 진행하지 않음으로서 리액트 파이버는 업데이트될 변경사항에 우선순위를 부여할 수 있게 되었다. -> "증분 렌더링"
증분 렌더링은 가상 DOM을 업데이트하는 작업을 분할하는 방식으로 작동하는데, 이를 위해서 재조정(위에서 언급한 커밋)과 렌더링(렌더)이 분리되었다.
2. Fiber 작동원리
React의 Fiber 구조는 current 트리와 workInProgress 트리, 총 두 가지 트리를 기반으로 한다.
urrent 트리는 현재 화면에 렌더링된 상태를 나타내고, workInProgress 트리는 이 current 트리를 복사한 후 변경 작업을 하는 임시 트리이다.
- 모든 작업은 현재 UI 렌더링을 위해 존재하는 current 트리를 기준으로 시작된다.
- 만약 업데이트가 발생할 경우 리액트에서 새로 받은 데이터로 workInProgress 트리를 빌드하기 시작한다.
- 이 workInPrgress 트리를 빌드하는 작업이 마무리되면 다음 렌더링에 이 트리를 사용한다.
- 이 workInProgress 트리가 UI에 최종적으로 렌더링되어 반영이 완료되면 currnet가 workInProgress 트리로 변경된다.
Fiber로 얻은 효과:
재조정하는 동안 다른 작업을 중지하지 않기 때문에 React는 필요할 때마다 작업을 일시 중지하거나 렌더링을 시작할 수 있게 됐다.
리액트 파이버의 도입으로 Error Boundary, Suspense, React.Lazy, Fragements 그리고 Concurrency Mode가 가능해졌다. (깔끔한 오류 처리)
'리액트 심화 스터디' 카테고리의 다른 글
🏄♀️ 리심스 3주차 - 리액트 렌더링 최적화 (2) | 2024.11.12 |
---|---|
[Week 3] Automatic batching, windowing, useMemo, useCallback (2) | 2024.11.12 |
[Week 2] 리액트 렌더링 프로세스, React fiber (2) | 2024.11.05 |
🏄♀️리심스 1주차 - 리액트 상태, 리렌더링 (5) | 2024.10.28 |
[Week 1] snap state, Context, Virtual Dom, Reconciliation (3) | 2024.10.28 |