OHLPstudy / Frontend

프론트엔드 관련
0 stars 0 forks source link

4. React 렌더링 과정 #3

Open ohdanini opened 2 months ago

ohdanini commented 2 months ago

notion url : https://www.notion.so/React-1c837c99640b4976a0d407a1ff1475cb

1. 웹 브라우저 렌더링 과정

HTML과 CSS 리소스를 기반으로 웹 페이지에 필요한 UI를 그려내는 과정

DOM(Document Object Model) - 문서 객체 모델

Image

Critical Rendering Path

Image

1) HTML 파싱 → DOM 생성

2) CSS 파싱 → CSSOM 생성

3) DOM + CSSOM → Render Tree 생성

- Render Tree는 웹 페이지의 “청사진”
- DOM에는 HTML로 작성한 요소들의 배치 및 모양을 기술한 정보가 있고 CSSOM에는 CSS로 작성한 요소들의 스타일링에 대한 정보가 있는데 이런 정보들을 결합한 것이 Render Tree

4) Layout 단계

- Render Tree를 기반으로 실제 웹 페이지에 요소들의 배치를 결정하는 작업
- 웹 페이지 안에 HTML 요소들이 어떤 위치에 어떤 사이즈로 들어갈 것인지 계산하는 과정

5) Paint 단계

- 실제로 요소들을 화면에 그려내는 과정

그러면 업데이트는 어떻게 이루어질까?

Image


2. React 렌더링

React는 브라우저에서 렌더링을 위해 자체 프로세스를 가지고 있으며, Render Phase와 Commit Phase로 나뉜다.

애플리케이션의 모든 컴포넌트는 현재의 props와 state를 기반으로 UI를 구성하고, 이를 바탕으로 브라우저에 제공할 DOM 결과를 계산한다.

React는 렌더링 최적화를 위해 업데이트를 최소화하며, 업데이트 발생 시 변경 사항을 모아 최소 횟수로 DOM을 수정하고 내부적으로 자동화한다.

Image

Image

VirtualDOM

Virtual DOM은 실제 DOM의 복제판으로, 메모리 상에서 존재하는 객체이다.

Virtual DOM을 사용하는 이유는 Layout과 Paint 과정에서 리소스 소모를 최소화하기 위해서이다.

React 렌더링의 기본 원리

  1. 컴포넌트 렌더링 결과로부터 Virtual DOM 생성
    • React는 컴포넌트를 실행하여 Virtual DOM을 생성한다.
  2. 변화가 생기면 새로운 Virtual DOM 생성
    • 컴포넌트의 상태나 props가 변경되면 React는 변경된 상태를 반영하여 새로운 Virtual DOM을 생성한다.
  3. Virtual DOM 비교 (Diffing)
    • React는 이전 Virtual DOM과 새로운 Virtual DOM을 비교하여 변경된 부분을 식별한다.
  4. 차이점이 있으면 이를 실제 DOM에 반영 (Reconciliation)
    • 식별된 변경 사항만 실제 DOM에 적용하여 업데이트한다. 이 과정은 최소한의 DOM 조작을 보장하여 성능을 최적화한다.

React 렌더링이 일어나는 경우


3. React 렌더링 과정

(Trigger) → 함수(컴포넌트) → (Render Phase) → 객체(VirtualDOM) → (Commit Phase) → DOM(RealDOM)

Image

Step1. Trigger Phase (트리거 단계 - Trigger a render)

트리거 단계는 렌더링을 유발하는 단계로, React가 컴포넌트를 렌더링할 필요가 있음을 인식하는 과정이다.

  1. 초기 렌더링

    • 사용자가 처음으로 애플리케이션에 접근하면, React는 ReactDOM.createRoot() 메소드를 호출하여 루트 컴포넌트를 렌더링한다.
    • 이 과정에서 처음으로 UI가 화면에 그려진다.
    ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
      <App />
    );
  2. 리렌더링

    • 컴포넌트의 상태가 업데이트되거나, props이 변경되었을 때 React는 자동으로 해당 컴포넌트의 렌더링을 트리거한다.
    • 이 상태 변화는 React의 상태 업데이트 함수가 호출될 때 발생하며, React는 이 변화를 큐에 추가하여 렌더링 작업을 순차적으로 수행한다.

Step2. Render Phase (랜더 단계 - React renders your components)

랜더 단계는 React가 컴포넌트를 실행하여 UI의 가상 표현(Virtual DOM)을 생성하는 과정이다.

이 과정에서 React는 변경이 필요한 요소들을 계산하고, 어떤 부분이 실제 DOM에 반영되어야 할지 결정한다.

Image

렌더링 프로세스에서 컴포넌트를 실행하여 이 결과와 이전 가상DOM을 비교하는 과정을 거쳐 변경이 필요한 컴포넌트를 체크하는 단계

  1. 초기 렌더링
    • root 컴포넌트 호출하고, 이를 통해 처음으로 Virtual DOM 생성한다.
      • 이미지 설명

Image

Image

  1. 리렌더링
    • 업데이트된 컴포넌트를 호출하고, 변경된 부분만 계산하여 다른 작업은 수행하지 않는다. (Diff)
    • 자식 컴포넌트가 존재할 경우 재귀적으로 호출한다.

이 과정에서 JSX로 작성된 코드는 React.createElement() 호출로 변환되며, 이는 자바스크립트 객체로 컴파일된다.

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"]}

Step3. Commit Phase (커밋 단계 - React commits changes to the DOM)

커밋 단계는 Virtual DOM에서 계산된 변경 사항을 실제 DOM에 반영하는 과정이며, 이 단계에서 변경된 부분만 실제 DOM에 업데이트한다.

커밋 단계가 완료되면 브라우저 렌더링 과정을 거치게 된다.

  1. 초기 렌더링
    • appendChild() DOM API를 사용하여 작성한 모든 DOM node를 화면에 추가한다.
  2. 리렌더링 조건이 발생한 경우
    • 이전 단계에서 계산된 변경 사항을 바탕으로 최소한의 작업만 수행하여 실제 DOM에 업데이트한다.
    • 이 과정에서 fiber 구조를 통해 Virtual DOM을 효율적으로 관리하며, reconciliation 과정을 통해 변경된 부분만 업데이트한다.


다음 발표에서는 React가 UI를 최적화하고, 불필요한 DOM 조작을 최소화하는 방법에 대해 다룰 예정입니다.

4. 레퍼런스

https://www.youtube.com/watch?v=eBDj0B0HbEQ

https://www.moonkorea.dev/React-렌더링-및-최적화-(1)

https://www.moonkorea.dev/React-렌더단계-커밋단계

https://www.moonkorea.dev/React-렌더링-및-최적화-(2)-React-memo

https://www.moonkorea.dev/React-렌더링-재조정

https://www.moonkorea.dev/React-렌더링-재조정과-key

https://narup.tistory.com/272#--%25--%EB%25A-%25-C%EB%25-D%25--%EB%25A-%25--%25--%EA%25B-%BC%EC%25A-%25--

https://ko.react.dev/learn/render-and-commit