728x90
반응형
React의 비교(diffing)알고리즘
why?
- render = 해당 함수가 처음부터 끝까지 실행되는 것 = React element tree를 만드는 것
- state, props가 갱신되면 render()함수는 새로운 React element tree를 반환
- React → 가장 효과적인 방법으로 생성된 element tree에 맞는 UI 갱신!
- 하나의 트리를 다른 트리로 변환하기 위한 최소 연산? → O(n3)…
- 굉장히 비싼 연산…
- React는 두 가지 가정에 기반한 O(n) 복잡도의 알고리즘 구현!
- 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
- 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해줄 수 있다.
비교 알고리즘(Diffing Algorithm)
- root 엘리먼트 비교
- 두개의 트리를 비교할 때 React가 가장 먼저 수행
- 이후 동작은 root 엘리먼트의 타입에 따라 달라짐
- 다른 엘리먼트 타입 일 경우
- React는 이전 트리를 버리고, 완전히 새로운 트리를 구축
- ex) <a>에서 <img>로 , <Button>에서 <div>로
- 이전 DOM 노드들은 모두 파괴
- 컴포넌트 → componentWillUnmount() 실행
- 루트 컴포넌트 아래 모든 컴포넌트 언마운트 = state 사라짐
- 새로운 DOM노드들이 DOM에 삽입
- 컴포넌트 → UNSAFE_componentWillMount() 실행 ⇒ componentDidMount() 실행
- DOM 엘리먼트 타입이 같을 경우
- React는 두 엘리먼트의 속성 확인
<div className="before" title="stuff" /> <div className="after" title="stuff" /> // 위에서 아래로의 비교 // -> DOM 노드 상 className만 수정
- → 동일 내역 유지 - 변경된 속성들만 갱신!
- DOM 노드 처리 끝나면, 해당 노드의 자식들을 재귀적으로 처리
- 같은 타입의 컴포넌트 엘리먼트
- 동일한 인스턴스 유지 → 렌더링 간 state 유지
- 새로운 엘리먼트 내용 반영하기 위해 현재 컴포넌트 인스턴스의 props 갱신
- 해당 인스턴스의 UNSAFE_componentWillReceiveProps() , UNSAFE_componentWillUpdate(), componentDidUpdate 호출 → render() 메서드 호출 → 비교 알고리즘이 이전 결과와 새로운 결과를 재귀적으로 처리
- React는 두 엘리먼트의 속성 확인
- 자식에 대한 재귀적 처리
- DOM 노드의 자식들을 재귀적으로 처리할 때
<ul> <li>Duke</li> <li>Villanova</li> </ul> <ul> <li>Connecticut</li> <li>Duke</li> <li>Villanova</li> </ul> // 모든 자식을 변경 -> 비효율!!
- keys
- 자식들이 key를 가지고 있으면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인
- DOM 노드의 자식들을 재귀적으로 처리할 때
- 고려사항
- React가 언마운트 - 다시 마운트 시키는 것은 아님!
- 여기서의 리렌더링 = 모든 컴포넌트의 render를 호출하는 것 ⇒ 재조정 규칙에 따라 렌더링 전후 변경된 부분만이 적용됨!
- React가 언마운트 - 다시 마운트 시키는 것은 아님!
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 |