TIL: DOM이란 무엇일까?
오늘 오전 수업 시간에 React에 대해 배웠는데요, 현재 Frontend에서는 React의 생태계가 현재 압도적으로 우세합니다. 여러 이유가 있지만, Virtual DOM(가상 DOM)의 등장이 매우 큰 영향을 끼쳤다고 생각합니다.
Virtual DOM이란 무엇일까요? Virtual DOM은 실제 DOM을 모방한 가상의 DOM에서 리렌더링이 필요한 부분을 비교하는 ‘DIFF’ 알고리즘을 통해 필요한 부분만 빠르게 리렌더링 하도록 하는 공간입니다.
이 가상의 DOM을 사용하는 이유는 실제 DOM에서는 많은 계산이 일어나기 때문에 전체를 렌더링하게 되면 계산 비용이 만만치않게 들어갑니다. 때문에 렌더링 최적화의 역할을 수행할 수 있는 것이죠.
그렇다면 DOM은 무엇일까요? DOM(Document Object Model)은 브라우저가 HTML을 JS가 알아듣도록 객체(Object) 형태로 트리 구조화를 한 것입니다. 비유를 들자면, HTML은 건축가가 설계한 ‘건축 설계도’, DOM은 설계도로 지어진 ’건축물’에 해당합니다.
이 DOM을 제대로 알기 위해서는 화면에 렌더링되기까지의 과정을 알아야할 필요가 있는데요, 화면에 렌더까지 다음과 같은 절차를 밟습니다.
- DOM 트리 생성
- CSSOM 트리 생성
- 렌더 트리 구축 (DOM 트리 + CSSOM 트리)
- 레이아웃(Reflow)
- 페인트(Repaint)
- 합성 (Composite)
각 구조를 간단하게 설명 드리자면,
DOM 트리 구조는 말 그대로 나무 모양처럼 뿌리부터 가지까지 뻗어나가는 형태로 이루어지는 구조를 말하는데요,
- Document : 트리 구조의 뿌리 부분. 전체 페이지
- Elements :
<body>,<header>, 등과 같은 태그 - Attributes : className, id, 등과 같은 속성
- Text : 실제 적힌 글자
위와 같은 요소들을 부모 <-> 자식 관계로 정립하고, 트리 구조로 구조화합니다.
CSSOM 트리 구조도 마찬가지로 스타일 데이터 파싱을 거쳐 부모 <-> 자식 관계로 정립하고, 트리 구조로 구조화합니다. 렌더 트리란 DOM 트리와 CSSOM 트리를 합친 뒤에 생성되는 트리입니다. 실제로 화면에 그려질 요소에 대한 부분만 포함하기 때문에 실제 화면의 레이아웃이나 페인팅 작업을 수행합니다. 레이아웃(Reflow) : 레이아웃은 렌더 트리를 바탕으로 각 요소가 화면 어느 위치에, 어떤 크기로 배치될지 계산합니다. 페인팅(RePaint) : 레이아웃으로 계산된 위치에 실제 색상을 입히는 과정입니다. 합성(Composite) : opacity, transition과 같이 아주 미세한 조정이라서 CPU 대신 GPU로 계산하기 때문에 매우 빠릅니다. (TMI : 실제로 opacity를 HMR로 반영했을 때 부드러운 애니메이션을 경험할 수 있습니다.)
추가로 DOM 트리와 렌더 트리의 차이점은 화면에 ‘보이는 영역을 다루냐’ / ’안보이는 영역도 다루냐’로 구분하는 차이점이 있습니다. (안보이지만 공간을 차지하는 visibility: hidden 속성은 렌더 트리에 해당)
결국 이런 과정으로 레이아웃 > 페인팅 > 합성 순으로 CPU 계산을 많이 잡아먹는데요, 리렌더링 될 때마다 레이아웃은 Reflow(재배치) -> Repaint(재색칠) -> Composite(합성) 과정을 전부 거쳐서 계산해야하고, 페인팅은 Repaint -> Composite 과정을 거치며, 합성은 Composite 과정만 거치기 때문입니다.
느낀점 : 따라서 React의 Virtual DOM이 이런 재계산 과정을 최소화함으로써 렌더 최적화를 이루었기 때문에 가장 많이 쓰이는 라이브러리로 사용되는 것이라고 생각합니다.
- #배움일기
- #DOM