React의 가상 DOM, Vue의 가상 DOM과 비교

 

가상 DOM이란?

DOM (Document Object Model)

브라우저가 제공하는 문서 객체 모델

HTML 요소를 트리 구조로 표현하며, 브라우저에서 렌더링되는 실제 DOM을 말한다.

실제 DOM은 업데이트가 발생할때마다 전체 DOM 구조를 다시 계산하고 렌더링한다.

 

가상 DOM (Virtual DOM)

메모리 상에서 실제 DOM의 경량화된 사본을 만드는 개념으로 DOM 상태를 Javascript 객체로 나타내어 빠르게 연산할수 있다. 실제 DOM 조작 전에 변경 사항을 비교하고 필요한 부분만 실제 DOM에 업데이트 하는 방식으로 성능 최적화를 하기 위하여 생성된다.

리액트는 가상 DOM을 업데이트 할때 최소한의 DOM 업데이트를 보장하기 때문에 복잡한 업데이트가 빈번하게 발생해도 실제로 더 빠르게 업데이트할 수 있고, 유지보수에도 용이하다.

 

 

 

React의 가상 DOM

React의 가상 DOM과 비교 알고리즘 

가상 DOM은 메모리상에 존재하는 실제 DOM의 경량 사본으로 리액트는 컴포넌트의 상태나 Props가 변경될 때마다 새로운 가상 DOM을 생성한다.

리액트는 이전의 가상 DOM과 새로 생성된 가상 DOM을 비교(diff)하여 변경된 부분만 계산하는데, 이때 변경이 없으면 건드리지 않고 변경이 있는 부분만 찾아내어 실제 DOM에 반영한다.

<div>
<p>텍스트만 변경될 경우</p>
</div>

텍스트만 변경될 경우 <p> 태그 노드는 유지되고 노드 내부의 텍스트 노드만 변경한다.

 

재조정(Reconciliation)

상태나 Props가 변경되면, UI를 효율적으로 다시 그리는 과정을 말한다.

DOM 트리구조를 위에서 아래로 순차적으로 비교하여(전체 비교는 아니다) 변경된 노드만 업데이트한다.

배열이나 리스트일 경우 key를 사용하여 재사용 여부를 판단해 불필요한 업데이트를 방지한다. 이때 key가 같으면 노드를 재사용하며 다를 경우 새로 생성한다.

 

React의 가상 DOM 업데이트 과정

1. 상태 또는 props 업데이트를 감지하게되면 해당 컴포넌트의 렌더링 함수가 호출된다. (리렌더링)

2. 변경된 상태를 기반으로 새로운 가상 DOM 생성한다.

3. 이전 가상 DOM과 2번에서 만들어진 가상 DOM을 비교하게되는데, 이때 재귀적 비교를 통해 변경된 노드를 찾는다. 이때 전체 가상 DOM을 비교하는게 아니라 최적화 방식으로 특정된 영역의 가상 DOM만을 비교한다.

    ㄴ 동일한 레벨에서 노드 유형이 동일한 경우에만 비교하며, 노드 유형이 다를 경우는 해당 노드를 완전히 교체한다.

    ㄴ key를 활용하여 고유성을 식별하며, key가 없거나 중복되면 리스트를 다시 비교하여 교체한다. (비효율적임)

    ㄴ 동일한 노드와 동일한 하위트리에서 변경사항이 없다고 판단되면, 해당 하위 트리를 비교하지 않는다.

 4. 실제 DOM에 필요한 변경사항을 최소화하여 패치한다.

 

리액트는 컴포넌트를 다시 렌더링 한 뒤 가상 DOM 비교를 통해 효율성을 유지한다.

불필요한 리렌더링을 방지하려면 개발자가 추가적인 최적화 작업(메모이제이션)을 할수있다.

 

 

 

Vue의 가상DOM 업데이트와 비교해볼까?

vue는 종속성 추적과 반응형 데이터 시스템을 활용해 React와는 다른 방식으로 실제 DOM 업데이트를 최적화한다.

ㄴ 종속성 추적 ? 데이터와 이를 사용하는 템플릿 또는 컴포넌트간의 종속성 관계를 추적한다. 이로인해 변경된 데이터와 그에 의존하는 부분만 업데이트가 가능하다. 

ㄴ 반응형 데이터 모델 ? reactive 또는 ref 같은 API로 반응형 데이터를 관리한다. 이 데이터는 기본적으로 proxy를 활요하여 데이터의 변화가 생기면 이를 즉시 감지하고 필요한 업데이트를 수행한다.

vue는 데이터 중심, react는 컴포넌트 중심으로 가상 DOM을 다룬다고 이해하면된다.

 

vue의 가상 DOM 업데이트 과정

1. reactiva, ref등을 통해 데이터 변경을 감지한다. 어떤 데이터가 어떤 DOM 노드와 연결되어있는지 추적한다. (종속성 추적)

2. 종속된 데이터가 변경된 경우에만 가상 DOM을 생성한다

3. 이전 가상 DOM과 2번에서 생성한 가상 DOM을 비교한다. (종속된 데이터가 변경된 부분만 비교)

4. 실제 DOM에 필요한 변경사항을 최소화하여 패치한다.

 

vue의 가상 DOM이 효율적인 경우?

부분 업데이트가 많은 경우에 종속성 추적으로 필요한 부분만 업데이트가 가능하고,

반응형 데이터 시스템을 활용하면 (reactive. ref) 객체 내부 속성 변경도 쉽게 감지하기에 같은 데이터 구조를 사용할 경우  vue가 더 효율적이라고 할 수 있다.

 

 

 

정말 가상 DOM이 빠를까?

가상 DOM을 사용하는 프레임워크가 성능상의 한계를 보일수 있다는 점에서 '가상 DOM이 무겁다'라는 주제가 제기되었다고한다. 이로인해 가상 DOM을 사용하지 않거나 더 가벼운 방식을 채택한 프레임워크, 라이브러리들이 등장했다. (ex: svelte, solid.js...)

가상 DOM은 실제 DOM 조작 전 변경 사항을 계산하는 단계가 존재하고, 메모리를 사용하여 저장하고 관리해야한다.

 

항상 가상 DOM이 좋은 것은 아니다.

프로젝트 규모나, 업데이트되는 빈도 혹은 구조에 따라 실제 성능이 다를 수 있다.

예를 들어 DOM의 변경사항이 거의 없거나 간단할때에 실제 DOM이 더 빠를 수 있다.

소규모 애플리케이션에서 DOM의 변화가 거의 없을 경우, 가상 DOM의 비교(diff) 연산이나 메모리 사용등이 불필요할 수 있다. 따라서 가상 DOM이 유리한 경우는 복잡하거나 빈도 높은 업데이트가 발생할때 유리할 것이다. (대규모 어플리케이션 일수록 유리)

 

 

+ Recent posts