본문 바로가기
Web Study/원티드 프리온보딩 4월 FE

프리온보딩 1주차 첫번째 강의

by 쿠리의일상 2023. 4. 3.

아직 리액트 할 줄 모르지만... 일단은 귀동냥을 해보기로 했다.

모르는 개념은 열심히 서칭했다.

 

vite 로 리액트 프로젝트 init 하기

npx create-react-app 대신 새롭게 나온 번들링 툴 (새로운 기술)

- 번들링이 매우 빨라짐

-> 빌드 시간이 빨라짐, 개발에 편함

- webpack, rollup, parcel 등을 ESBuild 라는 것으로 대체

- 리액트에서 타입스크립트는 필수!

 

VirtualDOM 역할

  • 최적화된 업데이트로 사용자 경험 개선 - 브라우저에 반영하기 전에 사전작업을 하는 것
  • 업데이트에 우선순위를 부여 - Animation 과 Text

 

Fiber

리액트의 핵심 알고리즘을 재구성한 새 재조정(Reconciliation) 엔진

리액트 Fiber 의 목표는 애니메이션, 레이아웃, 제스처, 중단 또는 재사용 기능과 같은 영역에 대한 적합성을 높이고 다양한 유형의 업데이트에 우선 순위를 지정하는 것

 

리액트는 애플리케이션에 존재하는 모든 현재 컴포넌트 인스턴스를 추적하는 내부 데이터 구조를 가지고 있으며,

이 데이터 구조의 핵심 부분은 메타데이터 필드를 포함하고 있는 Fiber 객체이다.

 

1. 리액트 렌더링/업데이트의 가장 작은 단위 (컴포넌트보다 더 작은 단위임)

2. work 라고도 함

3. 효율적인 업데이트를 위하여

- work 를 중지하고 필요 시 다시 시작이 가능

- 다른 종류의 work들에게 우선순위를 부여할 수 있어야 한다.

- 이미 완료된 work 를 재사용 가능해야 한다

- work 가 더이상 필요없게 되면 버릴 수 있어야 한다

 

사용자가 만든 리액트 컴포넌트는 리액트 조화 과정 내 fiber 에 대응됨

component -> element -> fiber

 

리액트는 브라우저 런타임에서 이 fiber 들을 활용하여 Virtual DOM 을 만든다.

fiber는 따지자면 트리 구조가 아닌 연결리스트로 연결되어 있다.

  • 컴포넌트 트리의 특정 시점에서 렌더링 해야하는 컴포넌트 타입의 유형
  • 이 컴포넌트와 관련된 prop, state
  • 부모 형제 자식 컴포넌트에 대한 포인터
  • 리액트가 렌더링 프로세스를 추적하는데 사용되는 메타데이터

를 Fiber 객체가 포함하고 있다.

 

렌더링 프로세스

렌더링이 일어나는 동안 리액트는 컴포넌트의 루트에서 시작하여 아래쪽으로 쭉 훑어보면서

업데이트가 필요하다고 플래그가 지정되어 있는 모든 컴포넌트를 찾는다.

 

플래스가 지정되어 있는 컴포넌트를 만난다면 FunctionComponent() 를 호출하고 렌더링된 결과를 저장한다.

컴포넌트 렌더링 결과물은 JSX 로 구성되어 있으며, 이는 js 가 컴파일 되고 배포 준비가 되는 순간에

React.createElement() 를 호출하여 변환된다.

// 일반적인 jsx문법
return <SomeComponent a={42} b="testing">Text here</SomeComponent>

// 이것을 호출해서 변환된다.
return React.createElement(SomeComponent, {a: 42, b: "testing"}, "Text Here")

// 호출결과 element를 나타내는 객체로 변환된다.
{type: SomeComponent, props: {a: 42, b: "testing"}, children: ["Text Here"]}

전체 컴포넌트에서 이러한 렌더링 결과물을 수집하여 리액트는 새로운 오브젝트 트리(가상돔)과 비교하여 실제 DOM을 의도한 출력처럼 보이게 적용해야 하는 모든 변경 사항을 수집한다.

이렇게 비교하고 계산하는 과정을 리액트에서 reconciliation 이라고 한다.

 

render()

1. Render phase : 함수를 실행하는 것이고 함수의 결과값(JSX, 객체, VirtualDOM node)과 이전 Virtual DOM node를 비교하는 과정을 통하여 diff 가 있다면 다시 그리라고 체크하라고 하는 것까지의 과정

2. commit phase : diff 를 real DOM 에 반영하는 과정

 

Triggering -> Rendering -> Committing

리액트가 DOM 을 커밋 페이즈에서 업데이트 한 이후, 요청된 DOM 노드 및 컴포넌트 인스턴스를 가리키도록 모든 참조를 업데이트 한다.

그 다음 useLayoutEffect 훅을 호출한다.

짧은 timeout 을 세팅한 이후, 이것이 만료되면 useEffect 를 호출한다. 이러한 단계는 Passive Effects 단계라고 한다.

 

렌더링은 DOM 을 업데이트 하는 것과 같은 것이 아니고 컴포넌트는 어떠한 가시적 변경이 없이도 컴포넌트가 렌더링 될 수 있다는 것이 중요하다.

 

 

Reconciliation (조화)

업데이트가 발생할 때 기존의 트리와 차이점을 비교하는 방법

DFS 로 트리를 Traverse 해줌

 

Render Phase

변화된 사항을 감지하여 새로운 virtualDOM 을 생성하는 과정

1. performUnitOfWork

2. beginWork

3. completeUnitOfWork

4. completeWork

일반적인 렌더링 동작

리액트의 기본 동작은 부모 컴포넌트가 렌더링 되면

리액트는 모든 자식 컴포넌트를 순차적으로 리렌더링 한다.

 

diffing 알고리즘

리액트의 render 함수는 jsx 문법에 맞는 리액트 요소를 반환한다.

이때 상태가 변하거나 프로퍼티가 변하여 DOM 를 업데이트해야 하는 경우에 변경된 부분만 감지하여 바뀐 부분만 업데이트 하는 방식을 취하는데, 이 변경된 부분을 감지하는 방법을 Diffing Algorithm 이라고 한다.

Virtual DOM 끼리의 비교를 의미하며 리액트는 이전 상태와의 비교를 위하여 항상 이전 상태의 VirtualDOM 사본을 유지함

 

DOM은 트리 구조이므로 변경된 부분을 감지하기 위해선 트리 구조를 비교해야 한다.

일반적인 트리 구조의 비교는 O(n^3) 의 시간이 소요되는 것으로 알려져 있어 비효율적으로 보이지만

리액트는 이를 Heuristic 한 방식을 사용하여 O(n) 의 시간에 해결하고 있다.