Virtual DOM은 Real DOM과 다르게 전체 중 바뀐 부분만 Reload합니다.
예를 들어, n개의 요소가 있고 그 중에 1개의 요소만 바뀌었다면, Real DOM은 1개의 요소를 바꾸기 위해 전체 n개를 Reload하지만, Virtual Dom은 이전 Snapshot과 비교해서 바뀐 부분만 Real DOM에서 바꿉니다.
<div className='before' title='stuff'/>
<div className='after' title='stuff'/>
React에서는 className만 바꾸면 된다는 것을 안다.
<div style={{color: 'red', fontWeight: 'bold'}} />
<div style={{color: 'green', fontWeight: 'bold'}} />
color만 바꾸면 된다는 것을 안다.
컴포넌트 인스턴스는 동일한 유지되어 렌더링간 state가 유지된다.
React는 새로운 엘리먼트의 내용을 반영하기 위해 현재 컴포넌트 인스턴스의 props를 갱신한다.
UNSAFE_componentWillReceiveProps(), UNSAFE_componentWillUpdate(), componentDidUpdate
다음으로 render() 메서드가 호출되고 비교 알고리즘이 이전 결과와 새로운 결과를 재귀적으로 처리합니다.
전체 DOM 트리를 비교/탐색하는데 사용되는 알고리즘은 일반적으로 O(n^3)의 복잡도를 갖습니다.
React는 2가지 힌트를 이용해서 O(n)까지 줄였습니다.
첫번째>
자식 태그는 부모의 영향을 받는다.
그러므로, 부모 태그의 type이 바뀐다면 자식 태그들은 탐색할 필요가 없이 트리 전체를 재구축한다.
/*div 안의 Counter와 span tag안의 Counter*/
<div>
<Counter />
</div>
<span>
<Counter />
</span>
컴포넌트 인스턴스는 componentWillUnmount()로 파괴되고,
새로운 DOM 노드들이 DOM에 삽입됩니다.
UNSAFE_componentWillMount()가 실행되고,
componentDidMount()가 이어서 실행되면서 이전 트리와 연관된 모든 state는 사라진다.
두번째>
깃헙에서는 line이 달라지면 code가 달라졌다고 생각한다.
/*전*/
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
/*후*/
<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
위와 같은 상황에서 Connecticut만 추가되었음에도 불구하고 위치에 따라 확인하기 때문에, 깃헙처럼 code가 모두 달라졌다고 인식한다.
이를 해결하기 위해서, key 속성을 사용한다. key 속성을 사용함으로써 key='2014'에 해당하는 값만 추가렌더링 하면 된다.
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
: 참고로 공식문서에서는 인덱스를 key를 사용하여 문제가 발생하는 경우를 소개하고,
이를 해결하기 위한 방법을 소개한다.
https://codepen.io/pen?&editors=0010
> 공식 문서
https://reactjs.org/docs/reconciliation.html
> 참조한 문서
https://www.huskyhoochu.com/virtual-dom/
공식 문서를 조금 더 살펴 보니, React 16부터 fiber 라는 아키텍쳐를 사용하고 있다고 한다.
관련 내용은 아래 링크를 참고하자.
https://github.com/acdlite/react-fiber-architecture
[Javascript] 비동기 처리(2): Promise ⭐ (0) | 2021.08.17 |
---|---|
[Javascript] Event Loop와 Call Stack ⭐ (0) | 2021.06.22 |
[MongoDB] Model Relationships Between Documents (3) (0) | 2021.06.10 |
[MongoDB] Model Relationships Between Documents (2) (0) | 2021.06.10 |
[MongoDB] Model Relationships Between Documents (1) (0) | 2021.06.10 |