React Virtual DOM 정리
가상돔을 이해하기 위해서 우선 브라우저 렌더링 과정을 알아야한다.
브라우저 렌더링 과정
- HTML 파일을 파싱하여 DOM Tree 생성
- CSS 파일을 파싱하여 CSS Object Model (CSSOM) 생성
- Render Tree를 통해 Layout(레이아웃) 생성
- 요소의 크기와 위치를 결정한다
- 이 과정을 reflow라고도 한다
- Painting을 통해 스타일을 생성한다
- 스타일 정보를 기반으로 실제 화면에 렌더링됨
요소 업데이트
document.getElementById('some-id').innerValue = 'updated value';
- 해당 ID를 찾기 위해 HTML을 파싱
- 해당 요소의 하위 요소를 제거
- DOM update, CSS update
- 레이아웃 업데이트
- 트리를 순회하며 화면에 다시 Repaint
Virtual DOM을 사용하는 이유
만약 DOM을 직접 조작하려고 한다면 브라우저는 파싱부터 시작하여 위 과정을 전부 반복하게 됩니다.
하지만 최근엔 CSR방식을 통해 돔을 업데이트하는 동작이 많아지고 점점 더 복잡해지기 시작했습니다.
따라서 돔을 성능적으로 업데이트하기 위한 방식이 필요했고 Virtual DOM이 등장하게 되었습니다.
Virtual DOM의 특징
Virtual DOM은 실제 DOM과 유사하게 생겼지만 프레임워크나 라이브러리같은 곳에서 사용되는 기능입니다. 실제 DOM의 업데이트를 효율적으로 관리하도록 도와주는 중간 단계로 사용되며 실제 DOM에 존재하는 모든 객체들이 Virtual DOM에서도 존재하지만 Virtual DOM을 통해 실제 DOM의 레이아웃을 직접 변경할 수 있는 기능은 없습니다.
이를 통해 Virtual DOM은 실제 DOM을 업데이트 하기 위해 보다 가볍다는 특징이 있습니다. 실제 DOM과 비교했을 때 class, style 등의 HTML 속성은 가지고 있지만 DOM API 메서드는 갖고있지 않습니다.
따라서 Virtual DOM을 조작하는 것으로는 화면에 아무것도 그려지지 않기때문에 실제 DOM을 조작하는 것보다 빠르고, 이를 통해 애플리케이션의 상태가 변경될 때마다 Virtual DOM이 우선적으로 업데이트 되게 됩니다.
Virtual DOM 동작과정
- 애플리케이션에 새로운 요소가 반영되면 Virtual DOM이 생성되고 트리로 표현
- 즉 요소가 변경될 때마다 새로운 Virtual DOM이 생성
- 새로운 Virtual DOM과 이전 Virtual DOM을 비교하고 변경 사항을 기록
- 실제 DOM에 반영할 수 있는 최적의 방법을 계산하여 업데이트된 요소만 리렌더링
실제 비효율적으로 생각될 수 있지만 Virtual DOM을 업데이트하는 데 시간이 많이 걸리지 않는다.
앞서 동작과정을 통해 React는 두 개의 Virtual DOM을 사용한다는 것을 알게되었는데, 현재 Virtual DOM과 이전 Virtual DOM을 비교하는 과정을 diffing 이라고 합니다.
diffing 과정을 거친 후 정확히 무엇이 업데이트 됐는지 파악하게 되며 이후 실제 DOM에 반영하기 위해 Batch(한꺼번에 처리) 방식을 활용하게 됩니다.
Batch 방식을 통해 실제 DOM에서 가장 오래걸리는 UI 렌더링 부분을 효율적으로 수행하게 됩니다. 이때 변경 사항을 실제 DOM에 변환하는 전체적인 프로세스를 Reconciliation이라고 하며 해당 과정을 수행하게 됩니다.
Virtual DOM | 실제 돔 |
원본 DOM의 경량 사본 | HTML 요소를 Tree로 만듬 |
JS 라이브러리, 프레임워크에서 사용 | HTML 요소 분석 후 브라우저에서 사용 |
조작 후 변경된 요소만 다시 렌더링 | 조작 후 전체 DOM을 다시 렌더링 |
가벼운 업데이트 | 무거운 업데이트 |
업데이트하기 위해 성능은 빠르고 UX 최적화 | 업데이트하기 위한 성능은 느리고 UX는 좋지 않음 |
일괄 업데이트를 수행 | 업데이트될 때마다 DOM을 리렌더링 |