본문 바로가기
source-code/React

Reconciliation (재조정)

by mattew4483 2023. 8. 16.
728x90
반응형

React의 비교(diffing)알고리즘

why?

  • render = 해당 함수가 처음부터 끝까지 실행되는 것 = React element tree를 만드는 것
    • state, props가 갱신되면 render()함수는 새로운 React element tree를 반환
    • React → 가장 효과적인 방법으로 생성된 element tree에 맞는 UI 갱신!
  • 하나의 트리를 다른 트리로 변환하기 위한 최소 연산? → O(n3)…
    • 굉장히 비싼 연산…
    • React는 두 가지 가정에 기반한 O(n) 복잡도의 알고리즘 구현!
      1. 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
      2. 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해줄 수 있다.

비교 알고리즘(Diffing Algorithm)

  1. root 엘리먼트 비교
    1. 두개의 트리를 비교할 때 React가 가장 먼저 수행
    2. 이후 동작은 root 엘리먼트의 타입에 따라 달라짐
  2. 다른 엘리먼트 타입 일 경우
    1. React는 이전 트리를 버리고, 완전히 새로운 트리를 구축
    2. ex) <a>에서 <img>로 , <Button>에서 <div>로
    3. 이전 DOM 노드들은 모두 파괴
      1. 컴포넌트 → componentWillUnmount() 실행
      2. 루트 컴포넌트 아래 모든 컴포넌트 언마운트 = state 사라짐
    4. 새로운 DOM노드들이 DOM에 삽입
      1. 컴포넌트 → UNSAFE_componentWillMount() 실행 ⇒ componentDidMount() 실행
  3. DOM 엘리먼트 타입이 같을 경우
    1. React는 두 엘리먼트의 속성 확인
      <div className="before" title="stuff" />
      
      <div className="after" title="stuff" />
      
      // 위에서 아래로의 비교
      // -> DOM 노드 상 className만 수정
      
    2. → 동일 내역 유지 - 변경된 속성들만 갱신!
    3. DOM 노드 처리 끝나면, 해당 노드의 자식들을 재귀적으로 처리
    4. 같은 타입의 컴포넌트 엘리먼트
      • 동일한 인스턴스 유지 → 렌더링 간 state 유지
      • 새로운 엘리먼트 내용 반영하기 위해 현재 컴포넌트 인스턴스의 props 갱신
        • 해당 인스턴스의 UNSAFE_componentWillReceiveProps() , UNSAFE_componentWillUpdate(), componentDidUpdate 호출 → render() 메서드 호출 → 비교 알고리즘이 이전 결과와 새로운 결과를 재귀적으로 처리
  4. 자식에 대한 재귀적 처리
    1. DOM 노드의 자식들을 재귀적으로 처리할 때 
      <ul>
        <li>Duke</li>
        <li>Villanova</li>
      </ul>
      
      <ul>
        <li>Connecticut</li>
        <li>Duke</li>
        <li>Villanova</li>
      </ul>
      
      // 모든 자식을 변경 -> 비효율!!
      
    2. keys
      • 자식들이 key를 가지고 있으면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인
  5. 고려사항
    • React가 언마운트 - 다시 마운트 시키는 것은 아님!
      • 여기서의 리렌더링 = 모든 컴포넌트의 render를 호출하는 것 ⇒ 재조정 규칙에 따라 렌더링 전후 변경된 부분만이 적용됨!
728x90
반응형

'source-code > React' 카테고리의 다른 글

react에서 long press 구현하기  (0) 2023.08.16
Inversion of Control  (0) 2023.08.16
React Query - Placeholder, Initial Data  (0) 2023.08.16
React Query - keepPreviousData  (0) 2023.08.15
useReducer  (0) 2023.08.15