1. DOM 이란?
DOM은 Document Object Model(문서 객체 모델)의 약자로, 웹 브라우저 안에서 HTML 문서에 "html 태그"들을 JavaScript가 접근과 조작할 수 있도록 메모리에 보관할 수 있는 객체로 만든 것이다.
즉 웹 페이지를 이루는 태그들을 자바스크립트가 이용할 수 있게끔 브라우저가 트리구조로 만든 객체 모델을 의미하며 DOM은 HTML과 자바스크립트를 서로 이어주는 역할을 하고 있다.

2. 기존 웹 브라우저 렌더링 방식과 발생할 수 있는 문제점
2-1. 기존 브라우저 렌더링 방식
- DOM Tree 형성 : 서버에서 보낸 HTML 파일을 브라우저가 해석(Parsing)하여 DOM 트리를 만든다.
- CSSOM Tree 형성 : 서버에서 보낸 CSS 파일을 브라우저가 해석(Parsing)하여 CSSOM트리를 만든다.
- Render Tree 형성 : DOM 트리 + CSSOM 트리를 합쳐 Render 트리를 만든다.
- Layout(Reflow) : Render 트리로 각 노드의 위치와 크기를 계산한 레이아웃을 만든다. 뷰포트(ViewPort)내에서 각 노드들의 위치와 크기를 계산한다.
- Paint(RePaint) : Layout 계산이 완료되면 이제 요소들을 실제 화면에 그리는 Paint 작업을 실행한다.
2-2. 기존 브라우저 렌더링 방식의 문제점
그렇다면 동적이고 사용자와 빈번한 상호작용을 해야하거나 다양한 변화가 일어나는 웹페이지에서는 매번 위의 렌더링 방식을 반복해야한다. 이것은 굉장히 번거로운 일이 될 수 있는것이다.

이러한 데이터의 잦은 변경이나 동적인 웹페이지 내 매번 Reflow, Repaint를 진행해야 하는 번거로움을 해결하기 위해 React에서는 V-DOM이라는 개념을 도입하여 문제를 해결하려 했다.
이처럼 V-DOM을 사용하는 것이 무조건적으로 좋은 성능을 가지고 효율적인 방식이 아니라 동적인 웹페이지에서 데이터의 잦은 변경이 있을 때 사용하고 규모가 작고 정적인 웹페이지의 경우 일반 DOM이 성능이 더 좋을 수 있다.
즉, 상황에 따라 어느쪽의 성능이 좋고 효율적인지 다를 수 있다.
3. V-DOM이란?
V-DOM(Virtual-DOM, 가상돔)은 실제 DOM의 변경사항을 빠르게 파악하고 반영하기 위해 내부적으로 가상의 DOM을 만들어 관리하는 것으로, 쉽게 말해 DOM의 변경사항들을 모아놓은 요약본이라고 할 수 있다.
V-DOM은 in-memory에 존재하여 실제로 랜더되지 않고 있다가 변경사항이 있을 때 V-DOM이 랜더된다고 생각할 수 있다.

위의 그림의 예시와 함께 V-DOM을 이해할 수 있는 쉬운 예시를 하나 들어보자.
만약 스케치북에 그림을 그리다가 잘못된 부분을 발견한다면 어떻게 할 것인가?
이때 DOM의 경우 기존 그리던 스케치북을 찢어버리고 새로운 스케치북에 잘못된 부분을 수정한 그림을 새로 그리는 것이다.
하지만 V-DOM의 경우 잘못된 부분만을 지워 수정하는 것과 비슷한 개념이라고 할 수 있다.
작은 규모의 레이아웃 변경(Reflow)이 발생한다면 여러번 수정하여 여러번 그리는 것(Repaint)하는 것이 아니라,
큰 규모의 수정사항들을 모아 한번에 RePaint하는 것이 V-DOM의 핵심적인 기능인 것 같다.
4. React에서 V-DOM을 활용한 랜더링 방식
React의 V-DOM에는 항상 두개의 V-DOM 객체를 가지고 있다.
- 랜더링 이전 화면 구조를 나타내는 가상돔 (수정 전)
- 랜더링 이후에 보이게 될 화면 구조를 나타내는 가상돔 (수정 후)
그렇다면 React에서 V-DOM을 활용하여 어떻게 효율적으로 랜더링을 진행할까?
- 변화가 일어나면 변화된 버전을 가상돔으로 바꾼 뒤 데이터가 업데이트 되면 전체 UI를 가상돔에 리렌더링한다.
- 렌더링 이전에 화면의 내용을 담고있는 첫번째 가상돔과 업데이트 이후에 발생할 두번째 가상돔을 비교해 정확히 어떤것이 변했는지를 비교한다. (DIffing)
- 리액트는 이를 통해 차이가 발생한 부분만을 (브라우저상의) 실제 DOM에 적용한다. (Reconciliation, 재조정)

'프론트엔드 > React' 카테고리의 다른 글
[React] Next.js Error (Waring: Expected server HTML to contain a matching <header> in <html> (1) | 2024.02.27 |
---|---|
[React] React Hooks (0) | 2024.02.14 |