React가 이전 Virtual DOM과 새로운 Virtual DOM을 비교해서 바뀐 부분을 찾아내는 과정을 '재조정'이라고 말씀드렸죠? React는 두 개의 Virtual DOM 트리를 비교하면서 다음 규칙에 따라 변경 사항을 찾아냅니다.
다른 타입의 노드
만약 비교하는 두 노드의 태그 이름(예: <div>와 <span>)이나 컴포넌트 타입(예: <LoginButton>과 <LogoutButton>)이 다르면, React는 이전 트리를 완전히 버리고 새로운 트리로 완전히 교체합니다.
같은 타입의 DOM 엘리먼트
두 노드의 태그 이름이 같다면(예: 둘 다 <div>), React는 속성(attributes)만 비교해서 바뀐 속성만 실제 DOM에 업데이트합니다. 예를 들어 className이나 style이 바뀌었다면 그것만 바꿔주는 거죠.
같은 타입의 컴포넌트 엘리먼트
두 노드가 같은 타입의 컴포넌트라면(예: 둘 다 <Button>), React는 컴포넌트 인스턴스는 그대로 유지하고 내부 상태(state)와 속성(props)만 업데이트합니다. 그리고 이 컴포넌트에 대해서 다시 재조정 과정을 진행합니다.
리스트와 Key 속성
여러 개의 자식 요소들을 처리할 때(예: 목록), React는 기본적으로 순서대로 비교합니다. 하지만 리스트 중간에 요소가 추가되거나 삭제되면 비효율이 발생할 수 있어요. 이때 key라는 특별한 속성을 사용하면, React가 각 요소를 고유하게 식별해서 훨씬 빠르고 정확하게 변경 사항을 찾아낼 수 있습니다. 이 key에 대해서는 잠시 후에 더 자세히 알아보겠습니다.
reconciliation flow
이런 재조정 과정 덕분에 React는 최소한의 작업으로 화면을 업데이트할 수 있습니다. 그런데 만약 화면에 바꿔야 할 내용이 아주 많거나 복잡하다면 어떻게 될까요?
예전의 React는 이 재조정 과정을 한 번에 끝내려고 했기 때문에, 가끔씩 화면이 잠시 멈추는 것처럼 보이는 문제가 있었습니다. 이 문제를 해결하기 위해 등장한 것이 바로
React 16 버전부터 도입된 Fiber 아키텍처는 React의 재조정 알고리즘을 근본적으로 재설계한 것입니다. 이전 방식(Stack Reconciler라고 불렸습니다)은 업데이트 작업을 시작하면 중간에 멈출 수 없이 끝까지 진행해야 했습니다.
그래서 복잡한 업데이트 작업 중에는 브라우저가 다른 중요한 일(애니메이션, 사용자 입력 처리 등)을 하지 못하고 화면이 버벅거리는 문제가 생길 수 있었습니다.
각 컴포넌트나 DOM 엘리먼트에 해당하는 작업 단위입니다. 이전에는 단순히 컴포넌트 인스턴스 정보만 있었다면, 이제 Fiber 노드는 해당 컴포넌트의 작업 상태, 우선순위, 다른 Fiber 노드와의 관계(부모, 자식, 형제) 등을 담고 있는 더 상세한 정보 객체입니다. 마치 각 작업마다 붙어 있는 상세 작업 지시서와 같아요.
이 Fiber 노드들은
연결 리스트
(Linked List)와
트리
(Tree) 구조를 혼합한 형태로 서로 연결되어 있습니다.
업데이트 작업을 아주 작은 단위(Fiber 노드)로 쪼개고, 각 단위 작업에 우선순위를 매길 수 있게 합니다. 그리고 더 중요한 작업이 생기면 진행 중이던 작업을 잠시 멈추고 그 중요한 작업을 먼저 처리할 수 있습니다. 이걸
협력적 스케줄링(Cooperative Scheduling)
이라고 부릅니다.
Fiber는 브라우저가 너무 오랫동안 멈추지 않도록, 작업을 잘게 나누어 잠깐씩 처리하고 브라우저에게 제어권을 넘겨주는 방식으로 동작합니다. 이렇게 하면 복잡한 업데이트 중에도 애니메이션이 부드럽게 재생되고 사용자 입력에 빠르게 반응할 수 있게 됩니다.
앞서 재조정 과정에서 리스트를 처리할 때 key 속성이 중요하다고 잠깐 언급했었죠? 이제 key가 왜 중요하고 어떻게 도움이 되는지 좀 더 자세히 알아봅시다.
여러 개의 비슷한 항목들을 목록으로 보여줘야 할 때가 많습니다. 예를 들어, 친구 목록이나 할 일 목록 같은 경우죠. React에서 이런 목록을 렌더링할 때는 보통 배열의 map() 함수를 사용합니다.
Strict Mode는 애플리케이션 내의 잠재적인 문제를 알아내기 위한 도구입니다. 이름처럼 '엄격한' 모드인데요, 실제 운영 환경에서는 아무런 영향을 주지 않고 개발 중에만 활성화됩니다.
Strict Mode는 불안정한 생명주기 메서드 사용, 예상치 못한 부작용 등을 감지하고 개발자에게 경고 메시지를 보여줍니다.
예를 들어, Fiber 아키텍처에서는 렌더 단계가 중단되고 재개될 수 있기 때문에, 렌더링 과정에서 부작용(side effect)이 발생하는 코드는 문제가 될 수 있습니다. Strict Mode는 이런 함수들을 의도적으로 두 번 호출해서 개발자가 문제를 미리 발견하도록 돕습니다.
Strict Mode를 사용하려면, 애플리케이션의 일부를 <React.StrictMode> 태그로 감싸주면 됩니다.
React 18 버전부터 공식적으로 도입된 동시성 기능은 Fiber 아키텍처의 장점을 극대화하는 새로운 기능들의 집합입니다.
핵심은 여러 상태 업데이트의 우선순위를 다르게 처리하여, 긴급한 업데이트(예: 사용자 입력 반응)가 덜 긴급한 업데이트(예: 데이터 로딩 후 화면 표시) 때문에 지연되지 않도록 하는 것입니다.
예를 들어 startTransition API를 사용하면, 특정 상태 업데이트를 '긴급하지 않음'으로 표시할 수 있습니다. 이렇게 하면 해당 업데이트 때문에 앱의 반응성이 떨어지는 것을 방지할 수 있습니다.