하나하나의 Element(HTML)들을 담고 있는 웹페이지를 Document라고 하는데, 이를 브라우저는 분석해 페이지를 띄워주는 방식입니다.
DOM이란 이런 HTML element들을 tree형태로 표현한 것 입니다.

Virtual DOM은 실제 DOM과 같은 내용을 담고 있는 복사본입니다. 복사본은 실제 DOM이 아닌 JS 객체형태로 메모리 안에 저장되어 있습니다.
Virtual DOM은 실제 DOM의 복사본이기 때문에, 실제 DOM의 모든 element과 속성을 공유합니다.
차이점은 브라우저에 있는 문서에 직접적으로 접근할 수 없다는 점인데요. 때문에 화면에 보여지는 내용을 직접 수정할 수 없다는 것입니다. 그렇다면 Virtual DOM은 왜 사용하는 것일까요?
document.querySelector(‘#title”).style.color = “red”;
새롭게 계산된 내용이 브라우저에 그려지는 방식으로 플로우가 진행되는 것입니다.
사실 DOM조작은 트리에 있는 정보를 업데이트시켜준다는 점, 그리고 빠른 알고리즘을 사용한다는 조건 하에선 그렇게 퍼포먼스적으로 무리가 있는 작업은 아닙니다.
하지만 이를 반복적으로 수행한다면? 충분히 무거워질 수 있는 작업이 되는 것이죠.
이렇게 등장한 개념이 Virtual DOM이라는 것입니다.
앞서 말한 것 처럼, 가상 DOM은 실제 DOM과 내용을 공유하는 복사본입니다.
하지만 실제 DOM과 다르게 직접적으로 브라우저 화면의 UI를 조작할 수 있게 해주는 API는 제공하지 않습니다. 가상돔은 메모리에 저장되어 있는 자바스크립트 객체에 불과하기 때문이죠. 때문에 가상돔에 접근하고 수정하는 것은 매우 가볍고 빠른 작업이 되는 것입니다. “실제 브라우저에 접근하는 것이 아니기 때문이죠.”
그렇다면 리액트는 어떤 식으로 가상돔을 활용해 보다 효율적으로 실제 DOM을 조작할까요!?
리액트는 항상 두개의 가상돔 객체를 가지고 있습니다.
- 렌더링 이전 화면 구조를 나타내는 가상돔
- 렌더링 이후에 보이게 될 화면 구조를 나타내는 가상돔
리액트는 STATE가 변경될 때마다 Re-Rendering이 발생하는데요. 이 시점마다 새로운 내용이 담긴 가상돔을 생성하게 됩니다. 실제 브라우저가 그려지기 이전에 말이죠.

렌더링 이전에 화면의 내용을 담고있는 첫번째 가상돔과 업데이트 이후에 발생할 두번째 가상돔을 비교해 정확히 어떤 Element가 변했는지를 비교합니다. 이를 리액트에선 Diffing이라고 표현합니다.
Diffing은 효율적인 알고리즘을 사용해 진행되기 때문에 어떤 Element에 차이가 있는지를 매우 신속하게 파악할 수 있게 됩니다.
리액트는 이를 통해 차이가 발생한 부분만을 (브라우저상의) 실제 DOM에 적용하게 되는 것이죠.
이 과정을 Reconciliation(재조정)이라고 합니다. 이 과정이 매우 효율적인 이유는 Batch Update때문인데요. 이는 변경된 모든 Element들을 집단화시켜 이를 한번에 실제 DOM에 적용하는 방식입니다.
만약 리스트안에 10개의 항목이 바뀌었다면 실제 DOM을 10번 반복해 수정하는 것이 아닌, 한 번에 집단화시켜 이를 적용한다는 점이죠.
DOM조작에 비용이 가장 많이 발생하는 지점은 브라우저에 화면을 그려주는 작업인 만큼 Batch Update는 변경된 Element를 별개로 그려주는 것이 아닌, 변경된 내용을 한 번에 받아와 이를 실제 DOM에 한번에 적용시켜준다는 점이 효율적이라는 것이죠.
https://callmedevmomo.medium.com/virtual-dom-react-%ED%95%B5%EC%8B%AC%EC%A0%95%EB%A6%AC-bfbfcecc4fbb
https://velog.io/@dongjun187/React-Virtual-DOM-%EA%B8%B0%EC%B4%88-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC