1. 리액트 렌더링 프로세스
렌더링 프로세스
리액트의 렌더링 과정은 두 가지 단계로 나뉜다.
1. Render phase
렌더 단계에는 구성 요소를 렌더링하고 변경 사항을 계산하는 모든 작업이 포함된다.
실제 DOM을 조작하지 않고 실제 DOM을 모방한 가상의 DOM을 생성한다.
이를 통해 리액트는 새로운 가상 DOM과 원래의 DOM를 비교하여 효율적인 렌더링을 수행한다.
2. Commit phase
커밋 단계에서는 변경 사항이 실제 DOM에 적용된다.
리액트는 현재와 이전 가상 DOM 트리 간의 차이를 기반으로 UI를 업데이트한다.
컴포넌트 업데이트 및 리렌더링
1단계: 렌더링 트리거
컴포넌트는 다음과 같은 상황에서 렌더링이 발생한다.
- 컴포넌트의 초기 렌더링
사용자가 처음 어플리케이션에 진입했을때 보여야 할 화면을 위해 초기 렌더링을 수행한다.
creatRoot를 통해 루트 컴포넌트를 호출하는 식으로 이루어진다.
import Image from './Image.js';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'))
root.render(<Image />);
- 컴포넌트의 리렌더링
컴포넌트가 처음으로 렌더링 된 후에는 set 함수를 통해 상태를 업데이트하면 추가적인 렌더링이 발생한다.
컴포넌트의 상태를 업데이트하면 자동으로 렌더링 대기열에 추가된다.
- 함수형 컴포넌트의 useState()의 두 번째 배열 요소인 setter가 실행되는 경우:
state의 변화는 컴포넌트의 상태 변화를 의미한다.
컴포넌트의 상태가 변화할때 렌더링을 발생한다. - props가 변경되는 경우:
부모로부터 전달받는 값인 props가 달라지면 이를 사용하는 자식 컴포넌트에서 변경이 필요하므로 리렌더링이 일어난다. - 컴포넌트의 Key props가 변경되는 경우:
리액트에서 key는 명시적으로 선언되어 있지 않더라도 모든 컴포넌트에서 사용이 가능한 특수한 props다.
일반적으로 key는 하위 컴포넌트를 선언할 때 사용된다.
2단계: 리액트 컴포넌트 렌더링
렌더링을 트리거한 후 리액트는 컴포넌트를 호출하여 화면에 나타낼 내용을 파악한다.
초기 렌더링에서 루트 컴포넌트를 호출하며, 이후 렌더링에서는 상태 업데이트가 일어난 컴포넌트를 중심으로 렌더링을 진행한다.
이 과정은 재귀적으로 이루어지며 모든 중첩 컴포넌트가 렌더링될 때까지 계속된다.
1주차에서 살펴봤던 가상 DOM을 활용한 Reconciliation 과정이 이 단계에서 이루어진다.
3단계: DOM에 변경 사항 커밋
렌더링이 완료되면 리액트는 DOM에 번경 사항을 반영하는데, 이때 렌더링 간에 차이가 있는 경우에만 반영한다.
- 초기 렌더링의 경우 appendChild() DOM API를 사용하여 생성한 모든 DOM 노드가 생성된다.
- 리렌더링의 경우 필요한 최소한의 작업을 적용하여여 DOM이 최신 상태를 유지하도록 한다.
2. React Fiber
React Fiber는 리액트의 새로운 리렌더링 엔진으로, 리액트 16 버전부터 도입되었다.
이는 렌더링을 더욱 효율적으로 수행하고 UI 업데이트를 부드럽게 하여 성능을 개선한다.
왜 Fiber를 도입했을까?
리액트 16 이전에는 Stack Reconciler가 사용되었다.
Stack Reconciler는 렌더링을 동기적으로 수행하고, 모든 작업을 한 번에 처리했다.
간단한 작업에서는 문제가 되지 않겠지만,
복잡하거나 고연산의 작업을 처리할 때는 main thread에 부담을 주어 성능 저하의 위험이 있었다.
이 문제를 해결하기 위해 도입된 것이 Fiber Reconciler이다.
Fiber는 작업을 우선순위에 따라 분할해 실행할 수 있는 구조를 도입하여,
더 이상 모든 작업을 동기적으로 진행하지 않고, 작업을 중단하거나 재개할 수 있다.
이 방식을 증분 렌더링(incremental rendering)이라고 한다.
Fiber의 작동 방식
Fiber의 렌더링 과정은 크게 렌더링 단계와 커밋 단계로 나누어진다.
이 두 단계로 렌더링 작업을 분리하여, 각 단계가 독립적으로 수행될 수 있다.
- 렌더링 단계: 우선순위에 따라 작업을 청크 단위로 나누어 처리
이를 통해 긴 렌더링 작업이 중단 없이 계속되는 것을 방지하고, 시간이 오래 걸리는 작업이라도 단계적으로 업데이트할 수 있게 한다. - 커밋 단계: 실제 DOM에 변경 사항이 반영
이 단계는 브라우저에서 DOM 업데이트와 같은 실제 UI 변화가 발생하는 단계로, 일단 시작되면 중단되지 않고 완료된다.
Fiber의 작동 원리
Fiber는 Fiber Reconciler가 관리하는 자바스크립트 객체이다. 이러한 Fiber를 노드로 갖는 트리를 Fiber 트리라고 한다.
Fiber 트리는 현재 상태를 담은 current 트리와 작업 중인 상태를 나타내는 workInProgress 트리 두 개로 구성된다.
- 작업 시작 시 current 트리를 기준으로 새로운 workInProgress 트리 생성
- 작업이 완료되면 workInProgress 트리가 UI에 반영
- current 트리를 workInProgress로 교체하여 새로운 상태 유지
Fiber의 장점
- 작업 단위 기반: 렌더링 작업을 작은 청크 단위로 나누어 처리한다.
각 작업은 독립적으로 실행되며, 이로 인해 긴 작업을 짧은 시간 동안 수행할 수 있다. - 우선순위 조정: 렌더링 작업의 우선순위를 동적으로 조정할 수 있다.
사용자 입력과 같은 중요한 작업은 더 높은 우선순위를 부여받고, 긴 렌더링 작업은 일시 중단될 수 있다. - 중단 가능성: 기존의 렌더링 모델에서는 작업이 완료될 때까지 중단할 수 없었지만,
Fiber는 작업을 중단하고 나중에 재개할 수 있는 기능을 제공한다. - 비동기 렌더링: 비동기 렌더링을 지원하여 대규모 애플리케이션에서도 부드러운 사용자 경험을 제공한다.
이는 특히 긴 리스트나 복잡한 컴포넌트 트리를 처리할 때 유용하다. - 일관된 상태 유지: 렌더링 중 상태를 유지하면서도 UI의 일관성을 보장한다.
'리액트 심화 스터디' 카테고리의 다른 글
🏄♀️ 리심스 3주차 - 리액트 렌더링 최적화 (2) | 2024.11.12 |
---|---|
[Week 3] Automatic batching, windowing, useMemo, useCallback (2) | 2024.11.12 |
🏄♀️ 리심스 2주차 - 리액트 렌더링 (2) | 2024.11.05 |
🏄♀️리심스 1주차 - 리액트 상태, 리렌더링 (5) | 2024.10.28 |
[Week 1] snap state, Context, Virtual Dom, Reconciliation (3) | 2024.10.28 |