- 발행일
[원티드]리액트 오픈소스 펼쳐보기
[원티드]리액트 오픈소스 펼쳐보기
이 글은 네이버 블로그에 2024년 9월 21일에 올렸던 것을 그대로 옮겨온 것입니다.
useState 같은 상태 관리 hook의 동작 원리
- useState에 closure개념이 사용되었다는 이유가 뭘까
- useState에서 객체나 배열을 사용하기 까다로운 이유가 뭘까
- useState를 선언할 때 반드시 const로 하는 이유가 뭘까
- useState는 비동기인가 동기인가
useMemo, useRef 잘 사용하기
useMemo, useRef를 효율적으로 사용하는 방법
- useRef는 어떻게 리렌더링이 되지 않게 했을까
- useMemo는 정말 최적화에 도움이 될까
- useState, useRef, useMemo가 React 관점에서 차이점은 무엇일까
useEffect 톺아보기
useEffect 잘 사용하기
- useEffect에서 dependency array 값을 감지하는 방법
- useEffect에서 cleanup 함수가 가지는 의미
- useEffect는 어떤 방식으로 동작할까
Fiber와 Reconciler
리액트 Virtual Dom 최적화를 위해 도입된 Fiber
- 동시성과 평행성
- 리액트가 Fiber 아키텍쳐를 도입한 이유
- 리액트에서 Fiber란
Fiber와 Reconciler
리액트의 성능 최적화는 개발자에게 중요한 관심사 중 하나입니다. 특히, 복잡한 UI가 빈번하게 렌더링될 때 성능 문제는 더욱 두드러집니다. 이러한 문제를 해결하기 위해 리액트 팀은 Fiber라는 새로운 아키텍처를 도입했습니다. 이번 글에서는 리액트에서 Fiber가 무엇인지, 그리고 Fiber가 Virtual DOM의 동작 방식을 어떻게 최적화하는지 살펴보겠습니다.
1. 리액트에서 Fiber란?
Fiber는 리액트의 새로운 재조정(Reconciliation) 알고리즘입니다. 리액트는 기존에도 가상 DOM(Virtual DOM)을 사용하여 UI 업데이트를 효율적으로 처리했지만, 복잡한 컴포넌트 트리 구조에서 성능을 최적화하는 데 한계가 있었습니다. 이러한 한계를 극복하기 위해 도입된 것이 바로 Fiber입니다.
기본적으로 리액트에서의 업데이트는 매우 빠르게 일어나지만, 컴포넌트 트리가 복잡해지면 업데이트 처리 시간이 길어질 수 있습니다. Fiber는 이러한 긴 작업을 분할하여 더 나은 성능을 제공하며, 특히 긴 작업을 중단하고 나중에 다시 이어서 할 수 있는 특성을 가지고 있습니다. 이를 통해 리액트는 더 부드럽고 빠른 UI 업데이트를 가능하게 합니다.
2. 리액트가 Fiber 아키텍처를 도입한 이유
리액트가 Fiber 아키텍처를 도입한 주된 이유는 **동시성(Concurrency)**을 개선하기 위함입니다. 리액트의 이전 버전에서는 업데이트 작업이 매우 단일하고 직선적으로 수행되었습니다. 하지만 Fiber를 통해 리액트는 긴 작업을 더 작은 단위로 나누고, 이 작업들을 우선순위에 따라 스케줄링하여 처리할 수 있습니다.
동시성과 우선순위 기반 작업 처리: Fiber는 작업을 여러 프레임에 걸쳐 나누어 처리하고, 중간에 다른 중요한 작업을 먼저 처리할 수 있도록 합니다. 이렇게 함으로써 CPU 사용을 최적화하고, 사용자 경험을 더 자연스럽게 유지할 수 있습니다.
중단 가능한 작업 처리: Fiber는 작업을 중단하고 다시 이어서 할 수 있는 기능을 제공합니다. 예를 들어, UI 업데이트와 같은 작업 중에 사용자 입력이나 애니메이션과 같은 긴급한 작업이 발생하면, 해당 작업을 먼저 처리하고 UI 업데이트는 나중에 다시 이어서 처리할 수 있습니다.
3. 동시성과 평행성
Fiber는 **동시성(Concurrency)**을 통해 성능을 최적화합니다. 동시성은 여러 작업이 겹쳐서 동시에 처리되는 것을 의미하는데, Fiber는 작업을 분할하고 이러한 분할된 작업들을 우선순위에 맞게 처리하여 UI 업데이트가 느려지지 않도록 보장합니다. 반면, **평행성(Parallelism)**은 여러 작업이 실제로 동시에 실행되는 것을 의미하지만, 자바스크립트는 단일 스레드로 동작하기 때문에 이 개념보다는 동시성이 더 중요하게 다뤄집니다.
리액트에서 동시성을 처리하는 방식은 사용자가 성능 저하를 느끼지 않도록 작업을 조절하는 것이 핵심입니다. Fiber는 이러한 동시성 처리의 근간이 되어 리액트가 복잡한 UI를 효율적으로 렌더링할 수 있게 합니다.
Q1: 리액트에서 Fiber가 기존 Virtual DOM과 어떤 점이 다른가요?
리액트의 기존 Virtual DOM은 트리 구조를 사용하여 변경 사항을 효율적으로 탐색하고 비교하는 방식으로 작동합니다. 그러나 이 방식은 큰 트리에서 많은 변경 사항이 발생할 때 성능에 한계가 있었습니다. 반면, Fiber는 Virtual DOM과 유사하게 트리를 탐색하지만, 작업을 쪼개고 우선순위에 맞게 스케줄링할 수 있는 능력이 있습니다.
기존 Virtual DOM은 한 번의 렌더링에서 모든 업데이트를 처리하려고 하는 반면, Fiber는 작업을 중단하고 나중에 이어서 처리할 수 있습니다. 이를 통해 리액트는 UI 업데이트 중에도 더 긴급한 작업(예: 사용자 입력 또는 애니메이션 처리)을 먼저 처리하고, 나머지 UI 업데이트 작업은 나중에 계속 처리할 수 있게 합니다. 이러한 방식은 긴 작업으로 인한 UI 응답성 저하를 방지하는 중요한 차이점입니다.
Q2: Fiber가 처리하는 작업의 우선순위를 어떻게 결정하나요?
Fiber는 작업을 처리할 때 우선순위(Priority)를 기반으로 스케줄링합니다. 작업의 우선순위는 보통 작업의 중요도와 긴급성에 따라 결정되며, 리액트 내부에서는 이를 자동으로 관리합니다.
주요 우선순위 요소는 다음과 같습니다:
사용자 상호작용: 사용자의 입력(예: 클릭, 키보드 입력 등)이나 애니메이션과 같은 즉각적으로 처리되어야 하는 작업은 높은 우선순위를 가집니다. 이러한 작업은 사용자 경험에 직접적인 영향을 미치기 때문에 최우선으로 처리됩니다.
렌더링 및 업데이트: UI에 변경 사항을 반영하는 작업은 일반적으로 중간 우선순위입니다. 렌더링 작업은 사용자 상호작용 작업보다는 덜 긴급하지만, 여전히 중요한 작업입니다. Fiber는 이 작업을 여러 프레임에 나누어 처리할 수 있습니다.
비긴급 작업: 데이터 업데이트나 백그라운드에서 처리되어야 하는 작업은 낮은 우선순위로 처리됩니다. Fiber는 이러한 작업이 사용자 경험을 저해하지 않도록 처리 시점을 유연하게 관리합니다.
리액트는 각 작업의 중요도에 따라 스케줄링을 동적으로 조정해, 사용자에게 부드러운 인터페이스 경험을 제공하는 데 초점을 맞춥니다.
Fiber 아키텍처가 도입된 후 리액트 성능 최적화에 따른 실질적인 효과
Fiber 아키텍처가 리액트에 도입된 후, 성능 측면에서 여러 가지 실질적인 개선 효과가 있었습니다. 이러한 개선은 특히 대규모 애플리케이션이나 복잡한 UI를 다루는 상황에서 더욱 두드러집니다.
1. UI 응답성 개선
Fiber의 가장 큰 효과 중 하나는 UI의 응답성 향상입니다. 이전에는 긴 렌더링 작업이나 복잡한 컴포넌트 업데이트가 한 번에 처리되면서 브라우저가 응답하지 않는 경우가 발생할 수 있었습니다. 하지만 Fiber는 작업을 여러 프레임에 나눠서 처리하고, 중간에 긴급한 작업(예: 사용자 입력, 애니메이션 등)이 발생하면 먼저 처리하는 구조입니다. 이로 인해 사용자가 UI와 상호작용하는 도중에도 업데이트가 차질 없이 이루어집니다.
예를 들어, 스크롤링 중에 리렌더링이 발생하면 기존에는 화면이 일시적으로 멈추는 문제가 있었지만, Fiber 도입 후에는 리렌더링 작업을 중단하고 스크롤 이벤트를 먼저 처리한 후, 다시 렌더링 작업을 이어나갑니다. 이를 통해 사용자에게 더욱 부드러운 경험을 제공합니다.
2. 우선순위 기반 작업 처리
Fiber는 작업을 우선순위에 따라 분리하고 스케줄링할 수 있는 구조입니다. 이를 통해 중요한 작업은 먼저 처리하고, 덜 중요한 작업은 나중에 처리하거나 대기할 수 있게 했습니다. 예를 들어, 컴포넌트 트리에서 변화가 많은 부분만 우선 처리하고, 백그라운드에서 실행되는 비긴급 작업(예: 데이터 처리)은 나중에 처리할 수 있습니다.
이러한 우선순위 기반 처리 덕분에 리액트는 큰 애플리케이션에서도 CPU 자원을 효율적으로 사용하고, 동시에 여러 작업을 관리하여 전체적인 성능을 개선할 수 있었습니다.
3. 중단 가능한 렌더링
Fiber는 렌더링 작업을 중단하고 다시 이어서 할 수 있는 기능을 제공합니다. 즉, 렌더링이 중간에 완료되지 않더라도 현재 상태를 저장하고 나중에 이어서 작업할 수 있는 구조로 개선되었습니다. 이전의 리액트는 한 번 시작한 렌더링을 모두 마칠 때까지 기다려야 했기 때문에, 큰 트리 구조의 컴포넌트를 렌더링하는 경우 프레임 드롭이 발생할 수 있었습니다.
Fiber는 이러한 문제를 해결하기 위해 협력적 스케줄링(Cooperative Scheduling)을 도입하여, 일정 시간이 지나면 작업을 중단하고 다음 프레임에서 계속 렌더링을 이어나갑니다. 이로 인해 프레임 손실 없이 렌더링을 수행할 수 있게 되어, 화면이 버벅거리는 현상이 줄어들었습니다.
4. 향후 기능 확장을 위한 기반
Fiber 아키텍처는 동시성을 지원하기 위한 기반 아키텍처로 도입된 만큼, 현재와 미래의 성능 최적화를 위한 유연성을 제공합니다. 예를 들어, Concurrent Mode 및 Suspense와 같은 리액트의 미래 기능들이 Fiber 위에서 동작하도록 설계되었습니다. 이러한 기능들은 더욱 복잡한 비동기 데이터 흐름과 UI 업데이트를 효율적으로 관리할 수 있어, 대규모 애플리케이션에서도 성능을 최적화할 수 있는 기반을 마련했습니다.
5. 애니메이션 및 사용자 인터렉션 최적화
Fiber는 애니메이션과 사용자 인터렉션을 우선적으로 처리할 수 있게 하여, 특히 모바일 환경에서 중요한 성능 최적화를 가져왔습니다. 애니메이션이 부드럽게 재생되고, 사용자의 클릭이나 입력에 즉각 반응할 수 있도록 개선되어, 사용자 경험이 전반적으로 향상되었습니다.