티스토리 뷰
리액트의 렌더링 로직, reconciliation
리액트 컴포넌트가 화면에 렌더링 되는 과정은 다음과 같다.
1. 리액트의 JSX가 React.createElement로 바벨에 의해 트랜스파일링됨.
2. React.createElement함수 호출에 의해 리액트 엘리먼트 트리가 반환됨.
3. React의 reconciliation 알고리즘에 의해 리액트 엘리먼트 트리를 재귀적으로 순회하면서 이전 트리와 현재 트리의 변경사항을 비교한다음 변경된 부분만 실제 DOM에 반영함 (Virtual-DOM)
기존 reconciliation의 약점과 React Fiber의 등장 배경
이런 알고리즘은 애니메이션에 약하다.
1. UI에서는 모든 변경사항을 즉시 반영할 필요가 없다.
2. 데이터에 의한 UI변경보다 애니메이션에 의한 UI변경이 더 우선순위가 높다.
v16 이전의 리액트는 이런 부분을 잘 처리하지 못했다.
이전버전의 리액트에서 reconciliation이 재귀적으로 일어난다고 했다. 재귀적이라는 말은 중간에 함수 호출을 끊을 수 없다는것이다. 무조건 리액트 엘리먼트를 전부 다 순회할때까지 자바스크립트 엔진을 독차지하게 된다.
근데 만약에 이런 상황에 애니메이션이 비동기로 동작하고 있다면? 애니메이션이 제때 실행되지 못해서 프레임이 누락된다. 16ms내에 프레임 하나를 찍어내야 화면이 부드럽게 보인다. 실제로는 브라우저의 다른 추가 작업들 때문에 10ms내에 프레임을 찍어내야한다.
컴포넌트는 props혹은 state가 변경되면 리렌더링된다. 리렌더링이 될때마다 위에 적은 3가지 과정이 계속해서 재반복된다. 리액트에게 화면을 렌더링하기까지 매 순간 주어지는 시간은 10ms이다. 이 시간 내에 프레임을 찍어야한다.
따라서, 트리를 전부 순회할때까지 멈추지 않는 기존의 reconciliation 방식은 변경될 필요가 있었다. 그래서 등장한것이 Fiber이다.
React Fiber의 등장
Fiber를 한마디로 얘기하면 다음과 같다.
자체 가상 스택을 사용하는 작업 단위
React Fiber가 등장하면서 스택을 재 구현 했다. 하나의 Fiber는 하나의 가상 스택 프레임을 차지하는 작업의 단위이다. 기존의 엔진에 구현된 스택에서는 스택 프레임에 있는 실행 컨텍스트를 멈췄다가 다시 재개하고 이런 작업을 할 수 없었다. 위 문제를 해결하려면 스택을 재 구현해야 했던것이다.
재귀는 멈출수없기에 Fiber는 재귀 대신 연결리스트를 사용한다. 작업이 끝나면 그 다음 작업을 링크를 타고 가서 하면 되는것이다.
React의 Element와 React Fiber Node는 1:1로 대응된다. 하나의 엘리먼트를 렌더링하는것을 하나의 작은 단위인 Fiber로 맵핑시킨것이다.
두 종류의 Fiber
current fiber, in progress fiber 두종류가 있는데 현재 피버는 이미 렌더링 된 것을 나타내고 진행중인 fiber는 현재 스택 프레임을 차지하며 렌더링이 진행중인 fiber를 나타낸다.
'React' 카테고리의 다른 글
컴포넌트의 네이밍 (0) | 2021.05.05 |
---|---|
리액트에서의 상태 관리 (kent) (0) | 2021.04.30 |
React Fiber 소개 (0) | 2020.08.03 |
React에서의 데이터 정규화(normalizr) (0) | 2020.07.30 |
[ver 2020.07.27] FrontEnd Architecture(Mobx, React, React-Router) (0) | 2020.07.27 |
- Total
- Today
- Yesterday
- hydrate
- design system
- promise
- Polyfill
- rendering scope
- async
- typescript
- reflow
- atomic design
- server side rendering
- reactdom
- useRef
- Action
- await
- state
- mobx
- props
- storybook
- type alias
- react hooks
- Babel
- Next.js
- webpack
- return type
- javascript
- computed
- es6
- reducer
- react
- useEffect
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |