Virtual DOM이란?
Virtual DOM은 말 그대로 가상 돔이다. 그런데, 가상 돔이 필요한 이유는 무엇일까? 이를 이해하기 위해서는 브라우저의 작동 방식에 대해 알아볼 필요가 있다.
브라우저 작동 방식
"브라우저 엔진" 과 "렌더링 엔진"은 무었일까?
그림에서 알 수 있듯이 브라우저 엔진은 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어해주는 엔진이다.
렌더링 엔진은 HTML documents와 웹 페이지의 리소스들을 브라우저에 시각적으로 출력해준다.
브라우저가 화면에 그리는 과정
- 요청과 응답
만약 브라우저에서 어떠한 링크를 누르거나 URL에 주소를 입력하고 엔터를 누르면 그 페이지 안에서 HTML요청이
이루어지고 해당 서버에서 HTML document를 응답으로 준다.
- HTML 파싱과 DOM 생성
브라우저는 HTML 소스코드를 파싱하고 DOM 트리를 생성한다. 이 DOM 트리는 데이터를 표현한 것인데,
여기에서는 HTML 태그들에 해당하는 노드와 태그 사이의 텍스트 청크에 해당하는 텍스트 노드가 들어가 있다.
DOM Tree의 루트 노드는 <html> 이다.
- CSS 파싱과 CSSOM 생성
브라우저 렌더링 엔진은 HTML을 처음부터 한 줄씩 순차적 파싱으로 DOM을 생성한다. DOM을 생성해 나가다
CSS를 로드하는 link 태그나 style 태그를 만나면 DOM 생성을 일시 중단한다. 그리고 link 태그의 html 어트리뷰트
에 지정된 CSS 파일을 서버에 요청하여 로드한 CSS 파일이나 style 태그 내의 CSS를 해석하여
CSSOM(CSS Object Model)을 생성한다. 이후 CSS 파싱을 완료하여 HTML 파싱이 중단된 지점부터 다시 파싱하기
시작해 DOM을 생성한다.
- 랜더 트리 생성
렌더링 엔진은 서버로부터 응답된 HTML과 CSS를 파싱하여 각각 DOM과 CSSOM을 생성한다.
그리고 DOM과 CSSOM은 렌더링을 위해서 렌더 트리로 결합된다. 렌더 트리는 돔트르의 일종이지만
완전하게 통일되지는 않는다. 렌더 트리는 스타일 정보를 알고 있기 떄문에 만약 당신이 div를
display: none; 숨겼다면 이는 렌더 트리에 포함되지 않는다. 즉, 화면에 렌더링되지 않는 노드들은 포함 되지 않는다.
완성된 렌더트리는 각 HTML 요소의 레이아웃(위치의 크기)를 계산하는 데 사용되며 브라우저 화면에 픽셀을
렌더링하는 페인팅 처리에 입력된다.
Reflow & Repaint
리플로우(reflow)는 문서의 일부 또는 전체를 다시 렌더링할 목적으로 문서에 있는 요소의 위치와 형상을 다시 계산하는 것을 말한다. 가끔 문서의 단일 요소를 리플로우 하려고 한다면 상위 요소와 뒤에오는 모든 요소를
리플로우 해야할 수도 있다. 리페인트는 이름에서 알 수 있듯이 요소의 가시성에 영향을 주지만 레이아웃에는 영향을
미치지 않는 것들을 다시 그리는 것을 말한다.(테두리, 색깔 등)
렌더 트리를 구성하는 데 사용된 입력 정보를 변경하면 리플로우, 리페인트 둘 중 하나 또는 모두 발생할 수 있다.
리플로우와 리페인트는 비용이 많이 들 수 있고 않좋은 사용자 경형을 줄 수 있으며 UI가 느려질 수 있다.
Virtual DOM vs Real DOM
DOM이 변경될 떄마다 브라우저는 CSS를 다시 계산해야 되고 레이아웃을 수행하고 웹페이지를 다시 칠해야 한다.
이 시간을 최소화하기 위해 Ember는 key/value observation 기술을 사용하고 앵귤러에서는 dirty checking을 사용한다. 이 기술을 사용하면 바뀐 돔 노드만 업데이트 하거나, 앵귤러의 경우 더럽혀진 노드(바뀐 노드) 만 업데이트를 할 수 있다.
그러나, 브라우저는 화면을 다시 그리는데 걸리는 시간을 단축하기 위해서 충분히 똑똑해졌다. 시간을 단축하는 것은 별로 중요한 요소가 되지 않게되었다. 이제는 리페인트를 발생하는 돔의 변화를 최소화하고 하나로 묶어 처리하는 것이
중요해졌다.
DOM 변화를 줄이고 일괄 처리하는 전략은 바로 virtual dom에 있다.
Virtual DOM은 정말 빠른가?
React에서 실제 DOM의 복사본 메모리를 저장한다. DOM을 수정하면 먼저 이러한 변경 사항을 메모리 내 DOM에 적용한다. (이것 또한 가상돔) 그런 다음 diffing 알고리즘으로 변화한 부붐을 파악한다. 마지막으로 변경 사항을 일괄 처리후
호출을 통해서 한 번에 실제 돔을 적용한다. 따라서, 리플로우와 리페인트를 최소화한다.
그렇다면 Virtual DOM은 정말 빠른 것인가
virtual dom이 real dom과 비교했을 때 절대적으로 빠른 것은 아니다. 단지 변경 사항을 최소화해 하나로 묶는
Real-dom에 적용하는 것 뿐이다.
참고 자료
'프론트 엔드 > React' 카테고리의 다른 글
[React] React Immutable (0) | 2022.01.17 |
---|---|
[React] React 조건부 렌더링 (0) | 2022.01.16 |
[React] JSX 문법이란? (0) | 2022.01.16 |