요즘 리엑트를 공부하면서 hook도 많고, 최적화 방법도 많아보여서 정신이 없다. 그 와중에 React는 virtual dom(가상 돔)을 사용 한다는데 얘는 또 뭐하는 놈인지 궁금해서 알아본다.
MDN에서는 DOM을 다음과 같이 정리한다.
문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 프로그래밍 interface 이다. DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM 은 nodes와 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.
즉 DOM은 브라우저가 받은 html 문서를 구조화 해, 접근가능하고 직접 조작할 수 있는 하나의 객체로 만들어 둔 API이다.
브라우저 렌더링 과정을 간단하게 요약하자면, 브라우저는 DOM과 CSSOM(css)을 통해 렌더트리를 만들고, layout(요소들의 위치 설정), painting(style 적용) 과정을 통해 결과적으로 화면에 페이지를 그려내며, 많은 연산과 비용이 드는 작업이다.
DOM을 조작하는 과정은 javascript 파일 안에서 이루어 진다. 이 말은 DOM 조작을 통한 html 문서의 변경이 렌더링 과정을 다시 불러온다는 것을 의미한다.
Virtual DOM은 메모리 안에 존재하는 javascript 객체 형태의 DOM의 가벼운 복사본이다.
설명의 간결함을 위해 여기서부터 virtual dom을 vd, real dom을 rd라고 칭한다.
vd는 rd의 복사본이지만 둘을 극명한 차이점을 지닌다. 바로 vd가 브라우저의 html 문서에 접근할 수 없으며, 단순한 javascript 객체라는 것이다. 이것이 vd가 가벼운 이유에 직결 된다.
vd는 rd와 다르게 문서에 접근할 수 있는 api 메서드를 가지지 않는다.
rd는 변경사항이 생기면 변경된 노드와 자식 노드를 삭제하고, 새로운 노드를 rd tree에 추가한다. 그리고 브라우저는 다시 렌더링이 된다. 이 과정은 변경사항이 생길때마다 작동한다.
vd는 변경점이 생기면 새로운 vd을 생성한다. 그리고 난 이후 원래 vd와 비교해 변경된 부분을 확인하고,
//virtual dom의 내부 구현체 중 diff함수
diff(previous: VTree1, current: VTree2) -> PatchObject
최종 변경사항을 rd에 적용한다.
//virtual dom의 내부 구현체 중 patch함수
patch(rootNode: DOMNode, patches: PatchObject) -> DOMNode newRootNode
여기까지만 보면 둘이 큰차이를 지니지 않는 것처럼 보이지만, vd와 rd의 변경이 이후로 관점을 이동시켜 보면 다른 결과를 볼 수 있다.
즉 여러개의 변경사항을 한번에 rd에 반영해 렌더링 횟수를 줄일 수 있다.
React에서는 Virtual DOM을 다음과 같이 설명한다.
Virtual DOM (VDOM)은 UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념입니다. 이 과정을 재조정이라고 합니다.
“virtual DOM”은 특정 기술이라기보다는 패턴에 가깝기 때문에 사람들마다 의미하는 바가 다릅니다. React의 세계에서 “virtual DOM”이라는 용어는 보통 사용자 인터페이스를 나타내는 객체이기 때문에 React elements와 연관됩니다.
즉 React는 재조명이란 과정을 통해 virtual dom을 real dom과 일치시킨다.
변경 전 후 두 개의 Virtual DOM을 비교해 변경사항을 찾는 과정
Virtual DOM이 무조건 빠르지는 않다. 결국 추가적인 메모리를 소비하고, 렌더링까지의 연산과정을 추가하기 때문이다. 이는 인터렉션이 별로 없는 페이지에서는 효율적이지 못하다.
이해가 잘 안돼서 유튜브 영상이나 글들을 찾아봤는데 그럼에도 낮설은 개념인것 같다. 추가적으로 svelte라는 컴파일러가 생겼고 더욱 빠르게 dom event를 처리한다고 한니, 나중에는 그쪽이 주류가 되는건가 싶다.
모르는 걸 하나씩 알아볼때마다 내가 모르는게 너무도 많다고 느낀다. 초보자들을 위해 쉽게 설명해주시는 분들 덕분에 조금씩 이해도를 채워나가는게 아닐까 싶다. 나도 언젠가 누구에게 그런 도움을 줄 수 있는 사람이 되고 싶다.
참고 사이트
React-문서-Virtual DOM과 Internals
youtube-우아한테크-돔하디-돔하디의 Virtual DOM
youtube-별코딩-React의 가상돔 (Virtual DOM)이 뭔가요? (짱 쉬움)
web.dev-Tali Garsiel, Paul Irish-How Browsers Work: Behind the scenes of modern web browsers