React에는 Virtual DOM이라고 하는 가상의 DOM 객체가 있다. 이는 실제 DOM의 사본 같은 개념으로, React는 실제 DOM 객체에 접근하여 조작하는 대신 이 가상의 DOM 객체에 접근하여 변화 전과 변화 후를 바교하고 바뀐 부분을 적용한다.
DOM은 Document Object Model의 약자로, 문서 객체 모델을 의미한다.
JavaScript와 같은 스크립팅 언어가 <head>
<body>
와 같은 태그들에 접근하고 조작할 수 있도록 태그들을 트리 구조로 객체화 시킨 것을 의미한다. 정리하면 DOM은 브라우저가 트리 구조로 만든 객체 모델이다.
이렇게 트리 구조로 DOM 객체가 이뤄져 있기 때문에 JavaScript는 쉽게 DOM객체에 접근할 수 있고 조작할 수 있다. 이러한 DOM은 애플리케이션의 UI상태가 변경될 때마다 해당 변경 사항을 나타내기 위해 업데이트가 된다. 만약 이런 DOM을 조작하는 정도가 잦다면 성능에 영향을 미치게 되고, DOM의 렌더링은 브라우저의 구동 능력에 의존하기 때문에 DOM의 조작 속도는 느려지게 된다.
자료구조 중에서 특히 트리는 데이터 저장의 의미 보다는 저장된 데이터를 더 효과적으로 탐색하기 위해 사용된다. 그렇기 때문에 트리 구조로 된 DOM은 JavaScript와 같은 스크립팅 언어가 접근하고 탐색하는 속도가 빠르기 때문에 변경 및 업데이트 속도 또한 빠르다.
그러나 DOM이 변경되고 업데이트가 된다는 것은 결국 브라우저의 렌더링 엔진 또한 리플로우 한다는 것을 의미한다. 즉 업데이트 된 요소와 그에 해당하는 자식 요소들에 의해 DOM 트리를 재구축함으로써 재렌더링 과정을 거쳐 UI를 업데이트 해야 한다. 브라우저의 리플로우와 리페인트 과정은 레이아웃 및 페인트에 해당하는 재연산을 해야 하기 때문에 속도가 그만큼 느려지게 된다.
결국 "바뀐 부분만 비교해서 그 부분만 렌더링을 할 수는 없을까?" 라는 아이디어를 기반으로 Virtual DOM 이 탄생하게 되었다.
React에는 모든 DOM 객체에 대응하는 가상의 DOM 객체가 있다. 상대적으로 무거운 DOM에 비해 React의 가상 DOM 객체는 실제 DOM 객체와 동일한 속성을 가지고 있음에도 훨씬 가볍다. 다만 가상 DOM 객체는 화면에 표시되는 내용을 실제 DOM 객체처럼 직접 변경하는 것은 아니다.
가상 DOM은 가상의 UI 요소를 메모리에 유지시키고, 그 유지시킨 가상의 UI 요소를 ReactDOM과 같은 라이브러리를 통해 실제 DOM과 같이 동기화 시킨다. 실제 DOM을 조작하는 것은 실제로 브라우저 화면에 그리기 때문에 느리지만, 가상 DOM을 조작하는 것은 실제 DOM 처럼 브라우저 화면에 그리는 것이 아니기 때문에 훨씬 속도가 빠르다.
React는 새로운 요소가 UI에 추가되면 트리 구조로 표현이 되는 가상의 DOM이 만들어진다. 이러한 요소의 상태가 변경이 되면 다시 새로운 가상의 DOM 트리가 만들어진다. 그리고 이전의 가상의 DOM과 이후의 가상의 DOM의 차이를 비교한다. 이 작업이 완료가 되면 가상의 DOM은 실제 DOM에 변경을 수행할 수 있는 최상의 방법을 계산하기 시작한다. 이렇게 하면 실제 DOM은 최소한의 작업만 수행해도 렌더링을 할 수 있게 된다.