본문 바로가기

react

[React] 파이버 아키텍처에 대한 개요

리엑트는 16버전부터 fiber 아키텍처를 채택하며 기존의 stack 아키텍처를 대체했고 지금까지 업데이트 중이다.

그럼 stack 아키텍처가 어떤 문제로 교체되었고 fiber 아키텍처는 어떤 특징을 가지고 있을까.

  • 리엑트의 파이버 노드 아키텍처가 어떤 맥락에서 등장하였고 어떤 결과를 가져왔는지에 대해 정리해보자.
  • 이 글은 파이버 노드 아키텍처의 구체적인 코드 분석을 다루지 않았다.

 

교체의 이유

배경지식. 리엑트의 기본 동작 과정

리엑트는 렌더링 프로세스에서 컴포넌트들을 호출하여 리엑트 엘리먼트를 만들고 이를 바탕으로 가상돔 트리를 형성한다. 그리고 커밋 프로세스에서 실제 돔 트리에 반영한다. 상태 값 변경으로 업데이트가 발생할 때는 비교 조정 과정(Reconciliation)이 일어난다. 이 과정은 루트 단계부터 시작되며 필요에 따라 재귀적으로 하위 컴포넌트까지 진행된다.

 

스택 아키텍처

스택 아키텍처는 이 동작 과정이 동기적으로 순차적으로 이뤄졌다. 즉, state 업데이트와 ui 갱신이 순차적으로 이뤄졌다는 의미다. 따라서, 단순한 업데이트에서는 예측하기 쉽게 작동했지만, 여러 state를 동시에 업데이트할 때는 성능이 좋지 않았다. 게다가 동기적으로 이뤄지는 업데이트는 자바스크립트의 콜스택을 차지하므로 이 동작 과정이 무겁고 복잡할수록 다른 작업이 밀리는 블록킹 문제가 발생했다. 특히 브라우저 렌더링 관련 작업이 막히면서 화면이 버벅이거나 상호작용이 안되는 문제가 발생했다. 그래서 나온 요구사항이 아래와 같다.

  • 작업을 비동기적으로 모아서 처리
  • 작업 간 우선순위를 설정
  • 특정 작업을 미루고 재시작 혹은 중단

 

파이버 아키텍처

파이버 아키텍처에서는 이런 문제를 해결하기 위해 비동기 업데이트와 스케줄링 기능을 구현했다. 이 아키텍처는 가상 돔의 각 노드를 파이버 노드로 설정한다. 파이버 노드는 객체 값으로서 ui에 대한 정보(type, props 등)를 가지고 있다.

 

비동기적 업데이트

파이버 아키텍처에서는 여러 state의 업데이트를 비동기적으로 함께 처리(batch update)한다. 이로 인해 순차적인 업데이트를 할 때에 비해 성능이 향상되며 중요한 작업을 우선 처리할 수 있다.

 

스케줄링

파이버 아키텍처는 작업에 우선순위를 설정할 수 있기 때문에 무거운 작업을 뒤로 미루거나 잠시 중단하고 재시작할 수 있다.

 

작업 우선 순위 설정, 중단 가능한 렌더링을 위한 기능들

파이버 아키텍처의 스케줄링 기능을 이용해서 코드 분할, 비동기적 렌더링, 에러 처리를 하는 방법들이다. 여기서는 간략히만 다루겠다.

 

Suspense

일반적으로 리엑트 컴포넌트들은 함께 렌더링되거나 되지 않는 "모 아니면 도"의 방식이다. 이 때문에 무거운 작업의 컴포넌트는 useState와 useEffect로 비동기적인 처리를 하는데, Suspense 컴포넌트는 이를 대신하여 보기 좋은 코드를 작성하게 해준다. 이것은 대상 컴포넌트 내 비동기 작업이 완료될 때까지 대기하며 그 동안 로딩 UI를 표시할 수 있다.  lazy loading을 위해서도 사용된다.

 

React.lazy()

React.lazy() 함수는 동적으로 컴포넌트를 로드하는데 사용한다. 즉, 최초 렌더링과 분리되어 필요 시에 코드를 가져오는 코드 분할을 할 수 있다. 이는 초기 렌더링에서 초기 로딩 시간을 줄일 수 있다. React.lazy()로 로드된 컴포넌트는 Suspense와 함께 사용하여 로딩 중에 대기 메시지를 표시하는 게 일반적이다.

 

Error Boundaries

Error Boundaries는 컴포넌트 트리의 하위 컴포넌트에서 발생한 JavaScript 오류를 처리하는 컴포넌트다. 이는 오류가 발생한 컴포넌트를 다른 컴포넌트로 교체하거나 오류 처리 메시지를 표시한다. 이를 통해 안정성을 유지하고 중단 가능한 렌더링을 지원할 수 있다.