리액트가 수많은 개발자들 사이에서 엄청난 사랑을 받는 이유중 한가지는 바로 빠른 속도입니다.
리액트는 가상돔(Virtual DOM)을 사용해 보다 효율적으로 우리가 원하는 페이지를 브라우저에 빠르게 그려주기 때문인데요.
리액트 개발자라면 한번 쯤 가상돔에 대해 들어봤을 법합니다.
이번 시간에는 가상돔에 대해 이해해보도록 하시죠!
DOM (Document Object Model)
하나하나의 Element(HTML)들을 담고 있는 웹페이지를 Document라고 하는데, 이를 브라우저는 분석해 페이지를 띄워주는 방식입니다.
DOM이란 이런 HTML element들을 tree형태로 표현한 것인데요.
DOM tree안에는 각각의 element에 상응하는 Node가 들어있는데요. 개발자들은 DOM이 제공하는 API를 통해 DOM구조에 접근을 하고, 원하는 Element를 입맛대로 조작할 수 있습니다. 이를 DOM 조작이라고 하죠. 흔히 getElementById나, querySelector 같은 API를 통해 돔 구조안의 Element에 접근해 원하는 대로 내용, 스타일, 레이아웃 등을 수정하는 것이죠.
그렇다면 Virtual DOM이라는 것은 무엇일까요?
Virtual DOM은 실제 DOM과 같은 내용을 담고 있는 복사본이라고 생각하시면 쉽습니다. 복사본은 실제 DOM이 아닌 JS 객체형태로 메모리 안에 저장되어 있습니다.
Virtual DOM은 실제 DOM의 복사본이기 때문에, 실제 DOM의 모든 element과 속성을 공유합니다. 차이점은 브라우저에 있는 문서에 직접적으로 접근할 수 없다는 점인데요. 때문에 화면에 보여지는 내용을 직접 수정할 수 없다는 것입니다. 그렇다면 Virtual DOM은 왜 사용하는 것일까요?
리액트는 이를 굉장히 똑똑하게 사용하고 있는데요. 이를 통해 실제 DOM을 조작하는데 걸리는 시간을 획기적으로 줄여줍니다.
만약 폰트의 컬러만 바꾸고 싶어도, 다음과같이 DOM조작을 필요로 하게 됩니다.
document.querySelector(‘#title”).style.color = “red”;
브라우저는 HTML을 탐색해 해당 Element를 찾고, 해당 Element와 자식 Element들을 DOM에서 제거합니다. 이후 새롭게 수정된 Element로 이를 교체하는데요. CSS는 이 과정 이후 다시 계산하여 결과적으로는 레이아웃 정보를 알맞게 수정하게 되는 것이죠. 새롭게 계산된 내용이 브라우저에 그려지는 방식으로 플로우가 진행되는 것입니다.
사실 DOM조작은 트리에 있는 정보를 업데이트시켜준다는 점, 그리고 빠른 알고리즘을 사용한다는 조건 하에선 그렇게 퍼포먼스적으로 무리가 있는 작업은 아닙니다.
하지만 이를 반복적으로 수행한다면? 충분히 무거워질 수 있는 작업이 되는 것이죠.
이렇게 등장한 개념이 Virtual DOM이라는 것입니다.
앞서 말한 것 처럼, 가상 DOM은 실제 DOM과 내용을 공유하는 복사본입니다.
하지만 실제 DOM과 다르게 직접적으로 브라우저 화면의 UI를 조작할 수 있게 해주는 API는 제공하지 않습니다. 가상돔은 메모리에 저장되어 있는 자바스크립트 객체에 불과하기 때문이죠. 때문에 가상돔에 접근하고 수정하는 것은 매우 가볍고 빠른 작업이 되는 것입니다. “실제 브라우저에 접근하는 것이 아니기 때문이죠.”
그렇다면 리액트는 어떤 식으로 가상돔을 활용해 보다 효율적으로 실제 DOM을 조작할까요!?
리액트는 항상 두개의 가상돔 객체를 가지고 있습니다.
- 렌더링 이전 화면 구조를 나타내는 가상돔
- 렌더링 이후에 보이게 될 화면 구조를 나타내는 가상돔
리액트는 STATE가 변경될 때마다 Re-Rendering이 발생하는데요. 이 시점마다 새로운 내용이 담긴 가상돔을 생성하게 됩니다. 실제 브라우저가 그려지기 이전에 말이죠.
렌더링 이전에 화면의 내용을 담고있는 첫번째 가상돔과 업데이트 이후에 발생할 두번째 가상돔을 비교해 정확히 어떤 Element가 변했는지를 비교합니다. 이를 리액트에선 Diffing이라고 표현합니다.
Diffing은 효율적인 알고리즘을 사용해 진행되기 때문에 어떤 Element에 차이가 있는지를 매우 신속하게 파악할 수 있게 됩니다.
리액트는 이를 통해 차이가 발생한 부분만을 (브라우저상의) 실제 DOM에 적용하게 되는 것이죠.
이 과정을 Reconciliation(재조정)이라고 합니다. 이 과정이 매우 효율적인 이유는 Batch Update때문인데요. 이는 변경된 모든 Element들을 집단화시켜 이를 한번에 실제 DOM에 적용하는 방식입니다.
만약 리스트안에 10개의 항목이 바뀌었다면 실제 DOM을 10번 반복해 수정하는 것이 아닌, 한 번에 집단화시켜 이를 적용한다는 점이죠.
DOM조작에 비용이 가장 많이 발생하는 지점은 브라우저에 화면을 그려주는 작업인 만큼 Batch Update는 변경된 Element를 별개로 그려주는 것이 아닌, 변경된 내용을 한 번에 받아와 이를 실제 DOM에 한번에 적용시켜준다는 점이 효율적이라는 것이죠.
오늘은 프론트엔드 개발자 면접질문으로도 자주 등장하는 개념인 가상돔에 대해 알아봤는데요! 큰 도움 되었길 바라면서 이만 물러가겠습니다~ 다음주도 행코하세요 :)