일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 이진탐색
- vue3
- C
- 웹팩
- 큐
- Machine Learning
- 알고리즘
- 브라우저
- 연결 리스트
- cors
- APOLLO
- RxJS
- 연결리스트
- alexnet
- 코딩테스트
- 해시테이블
- 릿코드
- 자료구조
- 스택
- pytorch
- RT scheduling
- 프론트엔드
- 컨테이너
- 배열
- GraphQL
- 타입스크립트
- 프로그래머스
- 자바스크립트
- 포인터
- 프로세스
- Today
- Total
프린세스 다이어리
DOM이 무엇인가? Virtual DOM이란? 리액트에서의 DOM은? 본문
1. DOM이란 무엇인가?
내가 IDE에서 작성한 HTML 코드는 DOM이 아니다. 단순한 문자열일 뿐이다.
DOM은 내가 작성한 HTML 코드를 실제 문서로 보여주기 위해 브라우저가 파싱해서 만든 노드 트리다.
이 DOM은 자바스크립트 API를 제공한다. 내가 작성한 HTML을 자바스크립트가 이해할 수 있도록 객체로 변환되었고 자바스크립트로 해당 문서에 노드 추가, 삭제, 변경, 이벤트 처리, 수정 등이 가능하다.
그래서 자바스크립트를 DOM API 라고도 부르는 것이다.
// 노드 추가
const newTextDiv = document.createElement('div')
const helloWorld = document.createTextNode('Hello world!')
newTextDiv.appendChild(helloWorld)
document.body.appendChild(newTextDiv)
2. Virtual DOM 이란 무엇인가?
(1) 브라우저가 HTML을 전달받으면, 이를 파싱해서 DOM트리를 만든다.
(2) 그리고 외부 CSS 파일과 인라인 스타일을 파싱해서 스타일을 입힌 Render 트리를 만든다.
(3) 그러면 각 노드들이 화면에서 정확히 어디에 나타나야 하는지에 대한 위치가 주어지는데, 여기서 paint() 메서드를 호출한다.
(4) 내가 구현하고자 한 화면이 브라우저에 출력된다.
DOM은 해당 과정을 계속 반복한다. 개발 작업 중 오타수정, 문구제거 등 사소한 일을 하거나 자바스크립트를 활용해 작은 수정이 들어가도, DOM은 (1)번부터 (4)번까지의 일을 반복한다. 그런데 브라우저의 성능은 렌더링 과정, 그 중에서도 reflow 과정이 가장 많이 잡아먹는다. 이 웹페이지가 수 백, 수 천 개의 페이지로 이루어져 있다면, 사소한 문구 수정에도 웹페이지 전체가 재렌더링 되기 때문에 브라우저가 연산을 많이 해서 전반적인 프로세스가 비효율적이게 된다. 그래서 Virtual DOM이 나왔다.
Virtual Dom(이하 가상 DOM)은 수정사항이 여러 가지 있더라도, 가상 DOM은 한 번만 렌더링을 일으킨다.
가상DOM은 DOM의 상태를 메모리에 저장하고, HTML에 변화가 있을 때만 구 가상돔(Old Node)과 새 가상돔(New Node)의 상태를 비교한 뒤 최소한의 변경된 내용만 한 번 반영하는 기능이다. 이를 통해 브라우저의 렌더링 연산의 양을 줄이면서 성능을 개선한다. 이런 변화들을 모아서 한 번에 처리하는 일종의 Batch 작업이라고 볼 수 있다.
또 가상DOM은 순수 자바스크립트 객체로 추상화되어 있어, 브라우저에 종속적이지도 않다. 그래서 가상 DOM을 사용하는 것은 실제 DOM에 접근하여 조작하는 게 아니라 자바스크립트를 조작하는 것이다. 이러한 이점으로 React Native와 같이 앱 개발 프레임워크도 만들어졌으며, 테스트하기도 용이하다.
3. 리액트가 가상돔을 반영하는 절차
특정 페이지에서 데이터가 변했다고 가정했을 경우,
(1) 데이터가 업데이트 되면 전체 UI를 Virtual DOM에 리렌더링한다.
(2) 이전 가상 DOM에 있던 내용과 현재의 가상DOM의 내용을 비교한다.
(3) 바뀐 부분만 실제 DOM에 적용한다.
따라서, 컴포넌트의 업데이트가 있으면 레이아웃 계산이 한번만 이루어진다.
'FE' 카테고리의 다른 글
[RxJS] 테스트코드 짜는 방법 (0) | 2022.05.19 |
---|---|
[RxJS] 중첩 Observable을 처리하는 3가지 방법 - mergeMap(), concatMap(), switchMap() (0) | 2022.02.28 |
[RxJS] Observable 스트림의 흐름을 합치는 3가지 방법 merge(), concat(), switch() (1) | 2022.02.27 |
프로미스 후속 처리 메서드(resolve, reject, all, race, allSettled) 정리 (0) | 2022.01.29 |
[Storybook] 스토리북 mdx 기본틀 잡기 (0) | 2022.01.28 |