💡 Real DOM의 가벼운 사본
💡 가상 DOM은 가상의 UI 요소를 메모리에 유지시키고, 그 유지시킨 가상의 UI 요소를 ReactDOM과 같은 라이브러리를 통해 실제 DOM과 동기화
💡 실제 DOM은 최소한의 작업만 수행해도 렌더링을 할 수 있게 됨
📗 DOM의 구조
DOM은 브라우저가 트리 구조로 만든 객체 모델
트리 구조로 되어있어 JavaScript는 쉽게 DOM 객체에 접근, 조작 가능
-JavaScript와 같은 스크립팅 언어가 접근하고 탐색하는 속도가 빠르기 때문에 변경 및 업데이트 속도 또한 빠름
-조작하는 정도가 잦다면 DOM의 조작 속도는 느려짐
📗 DOM의 업데이트
애플리케이션의 UI 상태가 변경될 때마다 업데이트 됨
-DOM이 업데이트 되면 브라우저의 렌더링 엔진도 리플로우함
-리플로우된 DOM트리를 다시 리페인트
-DOM의 요소가 많을 수록 DOM의 업데이트에 대한 비용이 많이 들게 됨
새로운 요소가 UI에 추가
➡️ 가상의 DOM 트리 제작
➡️ 이전의 가상의 DOM과 이후의 가상의 DOM의 차이를 비교
➡️ 가상의 DOM은 실제 DOM에 변경을 수행할 수 있는 최상의 방법을 계산
➡️ 실제 DOM은 최소한의 작업만 수행해 렌더링
💡 하나의 트리를 다른 트리로 변형을 시키는 가장 작은 조작 방식
💡 React는 비교할 때 트리의 레벨 순서대로 순회하는 방식으로 탐색
-너비 우선 탐색(BFS)의 일종
📗 DOM타입 비교
자식 태그의 부모 태그 또한 정해져 있다는 특징이 있음
다른 타입의 DOM
부모 태그가 변화하면 React는 기존의 트리를 버리고 새로운 트리를 구축함
이전의 DOM 노드들은 전부 파괴
-기존의 컴포넌트는 완전히 해제(Unmount)
-자식이 가진 기존의 state 파괴
//이전
<div>
<Counter />
</div>
//이후
<span>
<Counter />
</span>
같은 타입의 DOM
최소한의 변경 사항만 업데이트
업데이트 할 내용이 생기면 virtual DOM 내부의 프로퍼티만 수정, 모든 노드에 걸친 업데이트가 끝나면 그때 단 한번 실제 DOM으로의 렌더링을 시도
-재귀적으로 처리 하나의 DOM 노드를 처리하고 해당 노드들 밑의 자식들을 순차적으로 동시에 순회하면서 차이가 발견될 때마다 변경
//이전
<div className="before" />
<div style={{color: 'red'}} />
//이후
<div className="after" />
<div style={{color: 'green'}} />
📗 키 비교
key를 통해 이전 트리의 자식과 이후 트리의 자식의 일치 여부 비교
//이전
<ul>
<li key="1">a</li>
<li key="2">b</li>
</ul>
//이후
<ul>
<li key="3">c</li>
<li key="1">a</li>
<li key="2">b</li>
</ul>
✅ 형제 엘리먼트 사이에서만 유일하면 됨(전역은 필요 없음)
키가 없는 경우
React는 위에서 아래로 순차적으로 비교
처음 자식 노드가 이전과 다르다고 확인되면 전체가 바뀌었다고 판단,
이전을 모두 파괴하고 새로 렌더링하게됨
(비효율적)
//이전
<ul>
<li>a</li>
<li>b</li>
</ul>
//이후
<ul>
<li>c</li>//변화 감지
<li>a</li>
<li>b</li>
</ul>
✅ 키를 배열의 인덱스로 사용해도 마찬가지