akjfal

재조정(Reconciliation) 본문

(구)React 공식문서/고급 안내서

재조정(Reconciliation)

akjfal 2023. 2. 22. 19:13

재조정

React가 비교 알고리즘을 만들 때 어떠한 방법을 채택했는지에 대한 설명입니다.

Asnyc

하나의 트리를 가지고 다른 트리로 변환하기 위한 최소한의 연산 수를 구하는 알고리즘은 최첨단 알고리즘을 이용해도 n개의 트리에 대해 O(n3)의 복잡도를 가집니다. 이러한 연산은 너무 많은 연산이기 때문에, 2가지 가정을 추가하여 O(n)의 휴리스틱 알고리즘을 구현했습니다..

  1. 서로 다른 두 엘리먼트는 서로 다른 트리를 만들어냅니다.
  2. 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되면 안 되는지 표시해 줄 수 있습니다.

비교 알고리즘(Diffing Aligorithm)

두 개의 트리를 비교할 때 React는 root 엘리먼트부터 비교합니다. 이후 동작은 루트 엘리먼트의 타입에 따라 달라집니다.

엘리먼트의 타입이 다른 경우

두 루트 엘리먼트의 타입이 다르면 React는 이전 트리를 버리고 완전히 새로운 트리를 구축합니다. 트리를 버릴 때 이전 DOM의 노드들은 모두 사라지게 됩니다. 그리고 새롭게 트리가 생성될 때 새로운 DOM의 노드들이 DOM에 삽입됩니다.

DOM element의 타입이 같은 경우

같은 타입의 두 React DOM 엘리먼트를 비교할 때 React는 두 엘리먼트의 속성을 확인하여 동일 내용은 유지하고 변경된 속성들만 갱신합니다. style이 갱신될 때는 내부의 변경된 속성만 변경되며, 자식들은 재귀적으로 처리됩니다.

같은 타입의 컴포넌트 엘리먼트

컴포넌트가 갱신되면 인스턴스는 동일하게 되기 때문에 state가 유지되고, 내용 반영을 위해 props를 갱신합니다. 다음으로 render가 호출되어 비교 알고리즘이 이전 결과와 새로운 결과를 재귀적으로 처리합니다.

자식에 대한 재귀적 처리

DOM 노드의 자식들을 재귀적으로 처리할 때 React는 기본적으로 동시에 두 리스트를 순회하고 차이점이 있으면 변경을 생성합니다. 하지만 단순 비교를 한다면 맨 앞에 요소를 추가할 때 다르다고 판단하여 전체를 교체해야 하기 때문에 성능이 좋지 않습니다.

keys

자식들이 key를 가지고 있다면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인합니다. 만약 식별자를 가지고 있다면 해당 식별자를 그대로 사용하면 됩니다. 또한 형제들 사이에서만 유일하면되고, 전역에서 중복되어도 됩니다.

배열의 인덱스를 key로 사용할 수 있는데 항목들이 재배열 되지 않는다면 굳이 다른 방법을 사용할 필요가 없으나, 재배열 될 경우 비효율적으로 동작합니다. 왜냐하면 key가 순서가 바뀌었는데도 키의 위치는 그대로여서 컴포넌트 항목들이 제대로 바뀌지 않을 수 있기 때문입니다.

고려 사항

React는 휴리스틱에 의존하고 있기 때문에, 가정에 부합하지 않는 경우 성능이 나빠질 수 있습니다.

  1. 다른컴포넌트 타입을 갖는 종속 트리들이 일치 여부를 확인하지 않습니다. 비슷한 결과인 두 컴포넌트를 교체한다면 같은 타입으로 만드는 것이 더 나을 수 있습니다.
  2. key는 불변의 값이여야 합니다 .만약 random과 같이 변하는 값일 경우 불필요한 컴포넌트 인스턴스와 dom노트들이 재생성되어서 성능이 나빠지거나 자식 컴포넌트의 state가 유실될 수 있습니다.

'(구)React 공식문서 > 고급 안내서' 카테고리의 다른 글

Render Props  (0) 2023.02.22
Ref와 DOM  (0) 2023.02.22
JSX 없이 사용하는 React  (0) 2023.02.22
Profiler API  (0) 2023.02.22
Portal  (0) 2023.02.22
Comments