가볍게 읽고 지나가라는데, 난 가볍게 지나갈 수가 없는데..?

주요 키워드 Render phase, Commit phase, Side effect
리액트는 type과 props 그리고 key를 변경하게 되면 workInProgress tree에 반영하기 위해 Work함수를 실행시킨다(work는 scheduler에 의해 우선순위가 결정됨)
우선순위에 따라 현재 진행중인 task를 멈추고 이벤트처리와 같은 우선순위가 높은 task를 우선적으로 처리할 수 있다. 이 단계에서는 VDOM에서만 처리하기 때문에 실제 DOM에서는 적용되지 않는다.
work 함수란?
Reconciler가 컴포넌트의 변경을 VDOM에 적용하기 위해 행하는 작업
동기 렌더링 vs 비동기 렌더링
동기 렌더링 : 이 방식에서는 React가 UI 업데이트를 순차적으로 실행합니다. 한 작업이 완료되어야 다음 작업으로 넘어갈 수 있습니다. 이는 코드가 간단하고 예측 가능하지만, 무거운 작업의 경우 UI가 멈추거나 느려질 수 있습니다.
예시 : 사용자가 웹 페이지에서 "데이터 로드" 버튼을 클릭합니다. React는 fetchData 함수를 호출하여 서버에서 데이터를 가져옵니다. 이 함수가 데이터를 모두 가져올 때까지 UI는 멈춘 상태입니다. 데이터가 로드되면, UI가 업데이트되어 사용자에게 데이터를 표시합니다.import React, { useState, useEffect } from 'react'; export default function MyComponent() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchData = async () => { const response = await fetch("https://example.com/data"); const result = await response.json(); setData(result); setLoading(false); }; fetchData(); }, []); if (loading) { return <div>Loading...</div>; } return <div>Data: {data}</div>; }비동기 렌더링 : React의 Fiber 아키텍처를 통해 도입된 방식으로, 작업을 중단하고 재개할 수 있습니다. 이를 통해 React는 중요한 작업(예: 사용자 인터랙션)을 우선적으로 처리하고, 무거운 작업은 나중에 처리할 수 있어 애플리케이션의 반응성을 향상시킵니다.
예시 : 동일한 "데이터 로드" 버튼을 클릭합니다. 이번에는 React가 fetchData를 비동기적으로 호출합니다. 데이터 로딩 동안 사용자는 페이지에서 다른 인터랙션(예: 스크롤, 다른 버튼 클릭)을 계속할 수 있습니다. 데이터가 로드되면, React는 이를 감지하고 UI를 업데이트합니다. 이 과정에서 기존의 사용자 인터랙션은 방해받지 않습니다import React, { Suspense } from 'react'; const DataComponent = React.lazy(() => fetch("https://example.com/data") .then(response => response.json()) .then(data => ({ default: () => <div>Data: {data}</div> })) ); export default function MyComponent() { return ( <Suspense fallback={<div>Loading...</div>}> <DataComponent /> </Suspense> ); }
render phase에서는 render 작업까지만 진행되고, commit phase에서는 mount작업까지만 진행된다. 즉 paint 작업은 진행되지 않는다.
Commit phase는 계산할 필요 없이 완성된 current tree를 DOM으로 전달해야하기 때문에 일관된 UI 업데이트를 위해 동기적으로 실행되어야만 합니다.
리액트는 VDOM을 더블 버퍼링 형태로 관리하기 때문에 call stack과 다르게 workInProgress를 작업하다가 언제든 멈추고 삭제할 수 있다.
commitWork()가 실행되면(react fiber algorithm이 끝나면), workInTree를 가르키는 포인터만 바꿔서 current tree로 적용시킨다.
React element를 VDOM에 올려놓아야 한다. 그 확장을 fiber가 해줍니다. Fiber Node는 React의 Fiber 아키텍처에서 사용되는 기본 구조 단위이다. 이는 컴포넌트의 렌더링 상태, 출력, 다음 작업을 관리하기 위한 정보를 담고 있다. 각 Fiber Node는 컴포넌트의 인스턴스를 나타내며, React의 렌더링 엔진이 UI를 효율적으로 업데이트하고 관리하는 데 사용한다. Fiber 아키텍처는 비동기 렌더링을 가능하게 하며, UI 작업을 중단하고 재개하는 기능을 제공한다. 이를 통해 React는 더 복잡한 UI를 더 빠르고 효율적으로 처리할 수 있다.
지금까지 배운 걸 토대로 state가 변동 되는 과정(side effect)
1. setState를 호출되면 state 값이 변경
- 이 때, 이미 만들어져 있는 파이버 트리인 current tree를 토대로 workInProgress tree를 생성
- 업데이트 큐 설정
fiber 내부에 updateQueue가 존재 updateQueue란 컴포넌트 종류에 따라 element의 변경점 또는 라이프사이클을 저장
각자 fiber가 갖고 있는 고유의 key를 이용하여 work 함수가 변동된 state를 업데이트 큐에 넣는다.- Reconciliation
diffing algorithm을 이용하여 두 개의 tree를 비교하여 변동된 부분을 찾는다. DFS를 사용하여 트리를 순회 요기까지가 render phase- Commit
workInProgree에 연결되어 있는 포인터를 current로 옮기고 실제 DOM으로 옮겨진다. 이 때 UI는 변동되면 안되기 때문에 동기적으로 처리된다.- Paint
변동된 DOM을 가지고 브라우저는 paint 처리를 한다.