티스토리 뷰
Virtual DOM
- DOM은 문서 객체 모델(Document Object Model)의 약어로, 브라우저가 HTML 문서를 조작할 수 있도록 트리 구조화한 객체 모델입니다.
- 트리구조를 취하는 이유는 저장된 데이터를 더 효과이고 빠르게 탐색하기 위함입니다.
- Virtual DOM은 이런 DOM의 가벼운 복사본으로, React는 UI의 상태를 추적하고 변화가 일어난 요소들을 빠르게 업데이트 해주는 일종의 미들웨어라고 할 수 있습니다.
- Virtual DOM을 사용하는 이유는 DOM에서는 변화가 생길 경우, 변화되는 요소와 그의 자식까지 다시 재구축나 변화가 필요 없는 부분도 변경되면서 잦은 리플로우 발생하기 때문입니다.
- 리플로우로 인한 비효율적인 업데이트가 빈번하게 발생하게 되면, 프레임 레이트가 떨어져 화면이 버벅대거나 부드럽게 표시되지 않는 프레임 드롭이 발생할 수 있습니다.
- Virtual DOM은 실제 DOM과 동기화되며, 상태가 변경될 때마다 새로운 Virtual DOM을 생성하여 이전 상태와 비교합니다.
- 변경이 필요한 부분만 실제 DOM에 반영하여 업데이트하므로, 상태 관리의 용이성과 효율적인 업데이트 관리로 많은 개발자가 사용하고 있습니다.
브라우저의 렌더링 과정
브라우저의 렌더링 과정은 다음과 같은 단계로 이루어집니다.
- HTML 파싱: 브라우저는 서버로부터 받은 HTML 문서를 파싱하여 DOM(Document Object Model) 트리를 생성합니다. 이 트리는 HTML 요소, 속성, 텍스트 등 문서의 구조를 표현합니다.
- CSS 파싱: 브라우저는 HTML 파싱 중에 외부 CSS 파일과 내부 스타일 요소를 참조하여 CSSOM(CSS Object Model) 트리를 생성합니다. CSSOM은 문서의 스타일 정보를 표현하는 트리 구조입니다.
- 렌더 트리 생성: DOM 트리와 CSSOM 트리를 결합하여 렌더 트리(Render Tree)를 생성합니다. 렌더 트리는 실제로 화면에 표시될 요소들로 구성된 트리입니다. 하지만, 일부 요소는 렌더링에 영향을 주지 않는 숨겨진 요소이거나, CSS에 의해 표시되지 않는 요소 등은 렌더 트리에 포함되지 않을 수 있습니다.
- 레이아웃: 렌더 트리의 각 요소들의 크기와 위치를 계산하여 브라우저 창에서의 정확한 위치를 결정합니다. 이를 위해 브라우저는 요소의 크기, 위치, 여백 등을 고려하여 레이아웃을 수행합니다.
- 페인팅: 레이아웃이 결정된 후, 브라우저는 렌더 트리를 사용하여 실제 화면에 픽셀로 그리는 작업을 수행합니다. 이 과정을 페인팅(Paint)이라고도 합니다.
- 리플로우와 리페인트: 렌더링 과정에서 레이아웃이 변경되면, 해당 요소와 그것을 포함한 상위 요소들의 크기와 위치를 다시 계산해야 합니다. 이를 리플로우(Reflow)라고 합니다. 리플로우가 발생하면 페인팅도 다시 수행되어 화면을 다시 그려야 합니다. 이 과정을 리페인트(Repaint)라고 합니다.
이런 복잡한 과정을 거치기에 실제 DOM을 조작하는 것보다는 Virtual DOM 사용하는 것이 효율적입니다.
Virtual DOM의 형태
- Virtual DOM은 실제 DOM과 유사한 트리 구조로 표현되지만, 실제로는 추상화된 자바스크립트 객체의 형태를 가지고 있습니다.
const VirtualDOM = {
tagName: "html",
children: [
{ tagName: "head" },
{ tagName: "body",
children: [
tagName: "ul",
attributes: { "class": "list"},
children: [
{
tagName: "li",
attributes: { "class": "list_item" },
textContent: "List item"
}
]
]
}
]
}
- 추상화만 되었을 뿐 평범한 자바스크립트 객체이므로 실제 DOM을 건드리지 않고도 필요한 만큼 자유롭게 조작할 수 있습니다.
- 가상 DOM은 리액트에서 컴포넌트의 상태나 속성이 변경될 때마다 새로 생성되며, 리액트는 이전 가상 DOM과 새로운 가상 DOM을 비교하여 변경된 부분만 실제 DOM에 반영합니다.
- react는 상태를 변경하는 작업이 일어났을 때, 가상 DOM에 저장된 이전 상태와 변경된 현재 상태를 Diffing 알고리즘을 사용하여 비교합니다.
- 그리고 가상 DOM과 변경된 새로운 가상 DOM을 비교하여 변경이 필요한 부분만 실제 DOM에 반영하여 업데이트하는 Reconciliation(재조정)을 실행합니다.
- 만약 여러 개의 상태 변화가 있을 경우 이를 일일이 수행하지 않고 일괄적으로 한 번에 업데이트(Batch Update)하여 성능을 최적화하고 불필요한 리렌더링을 최소화합니다.
'개발 > React' 카테고리의 다른 글
React Hooks(useMemo, useCallback) (0) | 2023.05.20 |
---|---|
React Diffing Algorithm (0) | 2023.05.19 |
Redux Toolkit (0) | 2023.04.26 |
redux의 구조 (0) | 2023.04.24 |
redux 개요 (0) | 2023.04.24 |
댓글