Virtual DOM을 알기 위해서는 먼저 DOM의 개념부터 알아야 한다.
DOM은 Document Object Model을 줄임말이며, 문서 객체 모델을 의미한다. 여기서 문서 객체란 html, head, body 태그와 같이 javascript가 사용할 수 있는(메모리에 저장 가능한) 객체를 의미한다.
웹 페이지를 이루는 태그들을 자바스크립트가 이용할 수 있게끔 브라우저가 트리구조로 만든 객체 모델을 의미한다.
DOM트리가 만들어지는 과정: Browser와 렌더링 엔진
즉, DOM은 HTML과 javascript를 서로 이어주는 역할을 한다. DOM이 존재하기 때문에 javascript에서 HTML 태그들을 수정할 수 있다.
javascript에서는 document라는 전역 객체를 통해 HTML 태그에 접근할 수 있다. 또한 window라는 객체는 document객체의 상위에 위치한다.
참고자료: 벨로퍼트와 함께하는 모던 리액트
벨로퍼트님의 자료를 참고하자면, 인터렉션이 자주 발생하고, 이에 따라 동적으로 UI를 표현해야한다면, 이러한 규칙이 다양해질 것이고, 그러면 관리하기도 힘들어진다. 대부분의 경우 애플리케이션의 규모가 커지면, DOM을 직접 건드리면서 작업을 하여 코드가 난잡해지기 쉽다.
처리해야 할 이벤트도 다양해지고, 관리해야 할 상태값도 다양해지고, DOM도 다양해지게 된다면, 이에 따라 업데이트를 하는 규칙도 많이 복잡해지기 때문에, 조금 과장을 하자면 코드가 다음과 같은 형태가 된다고 한다.
그래서, 이를 해결하기 위해 여러 프레임워크가 등장했는데, 이 프레임워크들을 작동방식이 각각 다르지만, 쉽게 설명해 자바스크립트의 특정 값이 바뀌면 특정 DOM의 속성이 바뀌도록 연결을 해주어서 업데이트하는 작업을 간소화 해주는 방식으로 해결했다.
하지만 React의 경우에는 조금 다른 방식으로 동작하는데, React는 어떠한 상태가 바뀌었을 때, 그 상태에 따라 DOM을 어떻게 업데이트 할 지 규칙을 정하는 것이 아니라, 아예 다 날려버리고 처음부터 모든걸 새로 렌더링하는 아이디어에서 시작되었다.
그러면 업데이트를 어떻게 해야 할 지에 대한 고민을 전혀 안해도 되기 때문에 개발이 정말 쉬워진다. 하지만, 정말로 동적인 UI를 보여주기 위해 모든걸 다 날려버리고 모든걸 새로 만들게 된다면, 속도가 굉장히 느려지게 된다.
이러한 문제를 React에서는 Virtual DOM이라는 것을 사용해 가능하게 만들었다.
Virtual DOM은 가상의 DOM인데, 브라우저에 실제로 보여지는 DOM이 아니라 그냥 메모리에 가상으로 존재하는 DOM으로서 그냥 javascript 객체이기 때문에 작동 성능이 실제로 브라우저에서 DOM을 보여주는 것 보다 속도가 훨씬 빠르다. React는 상태가 업데이트 되면, 업데이트가 필요한 곳의 UI를 Virtual DOM을 통해서 렌더링한다. 그러고 매우 효율적인 알고리즘을 통해 실제 브라우저에 보여지고 있는 DOM과 비교를 한 후, 차이가 있는 곳을 감지하여 이를 실제 DOM에 패치시켜준다. 이를 통해 업데이트를 어떻게 할 지에 대한 고민을 하지 않으면서, 빠른 성능을 지켜낼 수 있게 되었다.
Virtual DOM은 실제 DOM에 접근하여 조작하는 대신, 이것을 추상화시킨 javascript 객체를 이용해 사용한다.
in-memory에 존재하기 때문에 실제 렌더되지 않는다.
Virtual DOM은 UI 가상 표현을 메모리상에 두고 재조정(Reconciliation) 과정을 통해 실제 DOM과 동기화하는 것을 말한다. 재조정 과정을 크게 3단계로 구성된다.
UI가 변경되면 전체 UI를 Virtual DOM으로 렌더링한다.
현재 Virtual DOM과 이전 Virtual DOM을 비교해 차이를 계산한다.
변경된 부분을 실제 DOM에 반영한다.
Virtual DOM을 사용하면 실제 DOM에 접근하는 대신, 추상화한 javascript 객체를 구성하여 사용하는데, DOM의 상태를 메모리에 저장하고, 변경 전과 후의 상태를 비교한 뒤 차이가 있는 곳을 감지하여 최소한의 내용만 반영하여 성능 향상을 이끌어낸다. DOM의 상태를 메모리 위에 계속 올려두고, DOM에 변경이 있을 경우에만 해당 변경 사항을 반영한다.
Virtual DOM의 주요 장정은 다음과 같다.
효율적인 "비교" 알고리즘(Diffing Algorithm)
단순하고 성능 향상에 도움이 된다.
React 없이 사용할 수 있다.
경량
상태 변경을 생각하지 않고 애플리케이션을 빌드할 수 있다.
Virtual DOM은 빠르고 효율적이지만 함정이 있다.
Virtual DOM에서 사용하는 "비교" 과정은 실제 DOM의 작업량을 실질적으로 줄여준다. 그리고 이 과정에서 변경 사항을 식별하기 위해 이전의 Virtual DOM과 현재 Virtual DOM 상태를 비교하는 일이 필요하다.
하지만 개발 과정에서 사소한 변경 사항이 굉장히 많이 일어나는 것을 볼 수 있고, 이렇게 UI의 각 요소를 비교하는 일은 오버헤드이다. 이것이 Virtual DOM의 단점이라고 할 수 있다.
이 글은 Incremental DOM과 Virtual DOM의 차이를 정리한 것은 아니지만 Incremental DOM과 Virtual DOM 중 결정해야 할 때, 속도와 메모리 사용량 사이에 트레이드오프가 있다고 한다.
참고
React에서의 가상돔 개념
[React] DOM이란? Virtual DOM을 사용하는 이유?
Incremental DOM과 Virtual DOM 비교