[TIL] 효율적인 렌더링을 위한 React Fiber의 이해

최소희·2024년 3월 3일
0

프론트엔드 학습

목록 보기
8/13
post-thumbnail

목표: React Fiber를 통해 React의 효율적인 렌더링 구조를 이해한다.

1. React Fiber 이전

  • 전통적인 리액트에서는 한 번에 하나의 작업만을 처리하며, 그 작업이 끝날 때까지 다른 작업을 중단하게 되는 동기식 렌더링으로 동작하였다. 이 방식은 간단하고 예측 가능하지만, 긴 작업이 실행되는 동안에는 사용자 입력이나 애니메이션 등이 블로킹되어 버리는 단점이 있었다.

2. React Fiber란 무엇인가?

  • Fiber는 React의 내부 알고리즘으로, 더 효율적인 UI 렌더링을 가능하게 하는 기술로 위와 같은 문제를 해결하게 되었다. 이를 통해 앱의 성능을 향상시키고 사용자 경험을 개선할 수 있다.

  • 구조: 컴포넌트 + 컴포넌트 input + 컴포넌트 output 에 대한 정보를 포함한 자바스크립트 객체

    • 컴포넌트 input(입력): 컴포넌트에 대한 입력 데이터를. 주로 컴포넌트의 속성(props) 및 상태(state)와 관련이 있다. Fiber는 컴포넌트가 렌더링될 때 이 입력 데이터를 참조하고 사용한다.
    • 컴포넌트 output(출력): 컴포넌트가 렌더링되고 나면, Fiber는 해당 컴포넌트의 출력 결과를 나타낸다. 출력은 일반적으로 Virtual DOM의 변경 내용을 포함하며, React는 이를 사용하여 실제 DOM을 업데이트한다.

3. 왜 React Fiber가 필요한가?

  • React Fiber의 주요 목표 중 하나는 애니메이션, 레이아웃 및 제스처와 같은 작업들을 더 부드럽게 처리할 수 있도록 하는 것이다. 비동기적인 방식으로 작동하여 작업을 세분화하고, 중요한 업데이트를 우선시하고, 덜 중요한 업데이트는 나중에 처리함으로써 사용자 경험 향상 및 성능 최적화를 할 수 있게 되었다.
    • 비동기 렌더링
    • 우선 순위 기반 스케줄링
      • 사용자 입력이나 애니메이션 등의 작업은 높은 우선 순위
      • 데이터를 불러오거나 대량의 상태 업데이트 등의 작업은 낮은 우선 순위

4. React Fiber의 주요 개념

4.1 재조정(Reconciliation)과 렌더링(Rendering)의 분리

React의 렌더링 프로세스는 크게 reconciliation과 rendering으로 나뉜다. Reconciliation은 가상 DOM 트리를 사용하여 이전 상태와 현재 상태 간의 차이를 계산하는 과정이다.

Fiber는 이 reconciliation 과정을 더 효율적으로 만들기 위한 것으로, 이전에는 한 번에 처리되던 업데이트를 작은 단위로 분할하여 우선순위를 부여하고 중단된 작업을 재개할 수 있도록 하는 방식을 도입한 것이다.

Rendering은 이 변경사항을 렌더러를 통해 특정 환경(ex. DOM)에 반영하는 작업이다.

이 분리로 인해 React DOM과 React Native가 동일한 Reconciler를 공유하면서도 자체 렌더러를 사용할 수 있다. Fiber는 Reconciliation을 주로 다루지만, 각 렌더러는 이를 기반으로 자체적인 업데이트 및 렌더링 로직을 구현하여 특정 환경(DOM, iOS, Android 플랫폼 등)에 맞게 동작하고 이것이 React가 다양한 환경에 적용할 수 있도록 하는 핵심적인 특성이다.

4.2 React Fiber의 주요 개념

  • Fiber는 작업 단위를 의미하며, 각각의 Fiber는 작업을 수행하는데 필요한 정보를 포함한다.
  • Fiber는 두 가지 단계, 즉 렌더 단계와 커밋 단계로 나누어진다.
  • 렌더 단계는 가상 DOM 트리를 구성하는 단계이며, 이 단계에서는 중단하거나 다시 시작할 수 있다.
  • 커밋 단계는 실제 DOM에 변경 사항을 적용하는 단계로, 이 단계는 중단할 수 없다.

4.3 React render 단계와 commit 단계

render 단계 (Reconciliation)
Reconciliation (재조정): 렌더 단계에서는 Fiber가 Virtual DOM을 통해 Reconciliation을 수행한다. Reconciliation은 현재 상태와 이전 상태의 차이를 계산하고, 업데이트가 필요한 부분을 결정한다. 이때 기준이 되는 것은 Virtual DOM이며, 컴포넌트의 상태나 속성 변경 등이 여기서 처리된다.

commit 단계 (Rendering)
Rendering (렌더링): 커밋 단계에서는 Reconciliation 단계에서 계산된 변경 사항을 실제 DOM에 반영한다. 이때 렌더러(Renderer)가 개입한다. 렌더러는 React의 특정 환경에 따라 DOM, Native (React Native), 또는 다른 환경에 변경 사항을 커밋하는 역할을 한다.

따라서, Reconciliation은 렌더 단계에서 일어나며, 커밋 단계에서는 렌더러가 Reconciliation에서 계산된 변경 사항을 실제 화면에 반영한다.

이 구조는 React Fiber가 더 효율적인 업데이트를 가능케 하는 중요한 특성 중 하나이다.

리액트의 렌더링이 일어난다고 해서 무조건 DOM 업데이트가 일어나는 것은 아니다.
렌더링을 수행했으나 커밋 단계까지 갈 필요가 없다면, 즉 변경 사항을 계산했는데 아무런 변경 사항이 감지되지 않는다면 커밋 단계는 생략될 수 있다.
즉, 리액트의 렌더링은 가시적인 변경이 일어나지 않아도 발생할 수 있다.

5. React Fiber의 장점

  • 비동기 렌더링: Fiber는 작업을 미세 조정하여 중요한 업데이트를 먼저 처리하고, 그 외의 업데이트는 나중에 처리하는 비동기 렌더링을 가능하게 한다.
  • 효율적인 계산: Fiber는 작업을 여러 개의 작은 단위로 나누어, 더 효유적으로 계산할 수 있게 한다.

6. 예시 코드

import React, { useState } from "react";

function App() {
  const [clicked, setClicked] = useState(false);

  const handleClick = () => {
    setClicked(true);
  };

  const items = Array(10000).fill().map((_, i) => <li key={i}>Item {i}</li>);

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
      <ul>{items}</ul>
    </div>
  );
}

설명

10000개의 항목을 렌더링하고 있는 코드가 함수 블럭 안에 있다.

기존의 리액트에서는 이런 경우, 모든 항목의 렌더링이 완전히 완료될 때까지 ‘Click me’ 버튼이 동작하지 않는다.

리액트가 렌더링 작업을 한 번에 처리하고, 그 작업이 완료될 때까지 다른 작업을 중단하기 때문이다.

리액트 파이버는 작업을 더 작은 단위로 나누어, 클릭 이벤트(우선 순위가 높음)가 발생했을 때, 1000개의 항목을 렌더링하는 작업을 잠시 중단하고 나중에 처리한다.

정리

React Fiber는 비동기적이고 효율적인 렌더링을 위한 내부 구조를 제공하며, Reconciliation은 어떤 부분이 변경되었는지를 계산하고, 렌더링은 변경된 부분을 실제로 화면에 업데이트(commit)하는 역할을 한다.
이를 통해 React는 더 나은 성능과 사용자 경험을 제공할 수 있다.

Reference

Modern React Deep Dive
react-fiber-architecture

profile
프론트엔드 개발자 👩🏻‍💻

0개의 댓글