리액트 파이버의 동작

2024. 12. 23. 17:25·React

파이버란?

  1. 리액트의 재조정(reconciliation) 엔진으로써의 의미
  2. React 컴포넌트에 대한 정보를 담는 자료구조로써의 의미

 

파이버 이전(~리액트 15) 스택 알고리즘의 한계

작업이 동기적으로 이루어져, 스택이 빌때까지 중단불가 → 리액트의 비효율성으로 이어짐.

ex) 자동완성 기능이 있는 검색 인풋의 경우 인풋 입력과 api 노출이 동시에 이루어질 수 없어 인풋 입력이 버벅이는 현상 발생

 

파이버의 작업 단계(리액트 16 ~)

  1. 렌더단계
    • VDOM을 업데이트하는 단계
    • 비동기실행
    • 작업의 우선순위 설정 및 중단,재시작, 폐기 수행렌더단계
  2. 커밋단계
    • DOM에 실제 변경사항 반영
    • 동기실행
    • 중단 없이 처리

실제 리액트 코드에서 구현되어있는 파이버 살펴보기

function FiberNode(tag, pendingProps, key, mode) {
  // Instance
  this.tag = tag
  -> 컴포넌트 유형 - 함수형인지 클래스형인지 프라그먼트인지,  호스트 컴포넌트(div같은 요소)인지
  this.stateNode = null
  -> 파이버 자체에 대한 참조 - 클래스 컴포넌트면 클래스컴포넌트명, div(호스트컴포넌트)면 div, 함수형 컴포넌트는 참조없음

  // Fiber
  this.return = null
  -> 부모 파이버
  this.child = null
  -> 자식 파이버 - 자식이 복수면? 그래도 첫번째 자식만 저장
  this.sibling = null
  -> 형제 파이버 - 형재가 복수면? 상관없음. 다음 sibilng 하나만 저장하고 마지막 파이버는 sibling에 null 저장
  this.index = 0
  -> sibling들 중 몇번째인지 나타내는 인덱스

  this.pendingProps = pendingProps
  -> 업데이트될 props
  this.memoizedProps = null
  -> 업데이트 이전 메모된 props - 렌더링이 완료되면 pendingProps로 덮어써진다.
  this.updateQueue = null
  -> 상태 업데이트, 콜백함수, DOM업데이트에 대한 작업을 담아두는 큐
  this.memoizedState = null
  -> 함수 컴포넌트의 훅 리스트가 저장됨.

  this.alternate = null
	-> 리액트 파이버 트리는 두가지(WorkInProgress, Current)인데 각 트리의 대응되는 파이버들이 서로를 가리킴
	...
}

 

파이버 트리

파이버트리는 리액트 내부에 2개가 존재

  1. Current 트리:
    • 실제 UI에 반영된 트리
    • WorkInProgress 트리가 UI에 최종적으로 렌더링 완료되면 Current 트리는 WorkInProgress 트리로 변경됨
  2. WorkInProgress 트리:
    • 작업 진행 중인 상태의 트리
    • 작업이 끝나면 리액트가 포인터를 변경해 Current 트리로 바뀜(더블 버퍼링)

 

파이버의 작업순서

    1. beginWork() 함수로 파이버 작업을 수행, 더 이상 자식이 없는 파이버를 만날 때까지 트리 형식으로 실행.
    2. 해당 파이버의 자식이 없으면 completeWork() 함수를 실행해 파이버 작업을 완료한다.
    3. 형제가 있다면 형제로 넘어간다.
    4. 2번 3번이 모두 끝났다면 return으로 돌아가 자신의 작업이 완료됨을 알린다.
    5. 최종적으로 comitWork()가 수행되고 변경사항을 비교해 DOM에 반영된다.

 

setState 등으로 업데이트가 발생한다면?

  • 최초 렌더링 이후에는 새로운 파이버를 생성하지 않음
  • 기존 파이버에서 업데이트된 props를 받아 내부에서 처리(가급적 새로운 파이버를 생성X)
  • 비동기로 실행이므로 작업이 공존하면 우선순위가 재조정되고 작업이 추가, 제거됨 (스택 알고리즘은 작업이 들어온 순서대로 순차 실행되었음)

 

저작자표시 비영리 변경금지 (새창열림)

'React' 카테고리의 다른 글

React useLayoutEffect  (2) 2024.12.27
React forwardRef와 useImperativeHandle  (0) 2024.12.27
리액트 Hooks와 클로저  (0) 2024.12.22
useEffect 사용시 주의해야 할 것들  (1) 2024.12.22
React Props: 원시값 vs 참조값 비교하기  (0) 2024.12.22
'React' 카테고리의 다른 글
  • React useLayoutEffect
  • React forwardRef와 useImperativeHandle
  • 리액트 Hooks와 클로저
  • useEffect 사용시 주의해야 할 것들
URE
URE
Skill: Javascript, ReactJS, Next.js, React Native ... *블로그 이전 작업(24. 04. 11 ~ 24. 04. 15)
  • URE
    Dev++
    URE
  • 전체
    오늘
    어제
    • 분류 전체보기 (51)
      • Browser (6)
      • OS (1)
      • Javascript (14)
      • React (19)
      • Next.js (4)
      • React Native (0)
      • Architecture (1)
      • Network (3)
      • 스크랩 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    TCP
    리액트
    dataFetching
    react
    JS
    원시타입
    브라우저
    URL
    상태관리라이브러리
    swr
    참조타입
    IP
    Port
    javascript
    Redux
    react18
    리덕스
    react concurrent
    자바스크립트
    리액트 코어
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
URE
리액트 파이버의 동작
상단으로

티스토리툴바