반응형
리액트 렌더링이란
컴포넌트의 props와 state를 기반으로 UI를 구성하고 이를 통하여 어떤 DOM결과물을 브라우저에게 제공할 것인지 계산하는 일련의 과정
리액트에서 렌더링이 일어나는 경우
- 최초 렌더링
- 리렌더링
- 클래스형 컴포넌트의 setState가 실행되는 경우
- 클래스형 컴포넌트의 forceUpdate가 실행되는 경우
- 함수형 컴포넌트의 useState의 setter가 실행되는 경우
- 함수형 컴포넌트의 useReducer의 dispatch가 실행되는 경우
- 컴포넌트의 key props가 변경되는 경우
- props가 변경되는 경우
- 부모 컴포넌트가 렌더링되는 경우
리액트 렌더링 과정
- 컴포넌트 트리의 최상단 루트로부터 아래로 내려가며 업데이트가 필요한 컴포넌트를 찾는다.
- 업데이트가 필요한 컴포넌트를 만나면 클래스형 컴포넌트는 클래스 내부의 render()함수를 실행하고 함수형 컴포넌트는 FunctionComponent 그 자체를 실행하고 결과물을 저장한다.
- 렌더링 결과물은 JSX문법으로 구성되며 자바스크립트가 컴파일되고 배포 준비가 되는 시점에서 React.createElement() 호출로 변환되며 createElement는 자바스크립트 객체 형식의 React Element를 반환한다.
- 이 렌더링 결과물을 수집하여 리액트의 새로운 Virtual DOM 트리와 비교해 실제 DOM에 반영할 변경 사항을 차례차례 수집한다. (Reconciliation)
// 다음과 같은 JSX 문법이:
return <SomeComponent a={42} b="testing">Text here</SomeComponent>
// 이런 식의 호출로 변환됩니다:
return React.createElement(SomeComponent, {a: 42, b: "testing"}, "Text Here")
// 그렇게해서 이런 엘리먼트 객체가 됩니다:
{type: SomeComponent, props: {a: 42, b: "testing"}, children: ["Text Here"]}
리액트 렌더링 과정은 개념적으로 2가지로 나뉜다
- 랜더 단계
- 컴포넌트를 렌더링하고 변경사항을 계산하는 모든 작업
- type, props, key 중 하나라도 변경된 것이 있으면 변경이 필요한 컴포넌트로 체크
- 커밋 단계
- 렌더 단계의 변경사항을 실제 DOM에 적용해 사용자에게 보여주는 단계
- 이 단계가 끝나야 브라우저 렌더링 발생
여기서 중요한 사실은 리액트의 렌더링과 DOM의 업데이트는 별개라는 것이며 컴포넌트는 어떠한 가시적인 변화가 없이도 렌더링될 수 있다는 점이다. 즉 렌더링을 수행하였는데 변경사항이 없다면 커밋 단계는 생략될 수 있다.
리액트 동시성 렌더링(Concurrent Rendering)
렌더와 커밋 단계로 이뤄진 리액트 렌더링은 항상 동기적으로 작동했다. 따라서 렌더링 과정이 길어질수록 앱의 성능저하로 이어지고, 결과적으로 그 시간만큼 브라우저의 다른작업을 지연시킬 가능성이 있다. 이는 렌더링 프로세스의 특징을 생각해보면 당연한데, 만약 순서가 보장되지 않는 비동기 방식으로 이뤄질 경우 사용자가 하나의 상태에 대해 여러 다른 UI를 보게될 수 있기 때문이다.
그러나 때로는 비동기 렌더링이 유효할 수 있는데, 가령 B컴포넌트의 렌더링 작업이 무거워 상대적으로 빠르게 렌더링 할 수 있는 A컴포넌트라도 변경해서 보여줄 수 있다면 그것이 더 좋은 방향일 것이다. 이처럼 의도된 우선순위로 컴포넌트를 렌더링해 최적화할 수 있는 비동기 렌더링, 이른바 동시성 렌더링이 리액트 18에서 도입되었다.
자바스크립트는 싱글스레드인데 어떻게 동시성 렌더링이 가능할까?
여러 작업을 작은 단위로 나눈 뒤 작업들 간의 우선순위를 정해 작업을 번갈아 수행하는 것이다.
작업 간의 전환이 매우 빠르게 이루어져서 동시에 여러 작업이 수행되는 것처럼 보이게 되는 것.
반응형
'개발이야기 > 웹개발' 카테고리의 다른 글
[코드잇 스프린트 풀스택 4기] 리액트 배열 렌더링 시 key를 지정해야 하는 이유 (0) | 2024.12.10 |
---|---|
[코드잇 스프린트 풀스택 4기] 리액트 useMemo, useCallback (0) | 2024.12.10 |
[코드잇 스프린트 풀스택 4기] 리액트(React) 컴포넌트 (0) | 2024.11.25 |
[코드잇 스프린트 풀스택 4기] React Virtual DOM (0) | 2024.11.25 |
[코드잇 스프린트 풀스택 4기] 렉시컬 스코프(Lexical Scope) (0) | 2024.11.25 |