Virtual DOM 넌 누구냐

하얀족제비·2021년 7월 6일
0

리액트

목록 보기
4/4

Virtual DOM

✨Why?

React의 작동 방식에 대해서 확실히 이해하고 넘어가기 위해서 공부하게 되었다.

Virtaul DOM을 찾아보면서 초보인 나한테는 사전적으로 알아야 할 기본 개념 및 지식들이 조금 많이 있었던 것 같다.

그러한 것들 부터 하나하나 이해하고 정리해보려고 한다.

1. 브라우저

웹 서버에서 이동하며 양방향으로 통신하고 HTML문서나 파일을 출력하는 GUI기반의 응용 소프트웨어

검색해보면 브라우저에 대한 개념이 방대하게 잘 정리되어 있다.

많은 글들을 읽어보고 내가 가장 직관적으로 이해할 수 있게 정리해보면

사용자의 요청에 의해 서버에서 응답으로 온 자원들(HTML 등)을 화면에 출력해주는 소프트웨어 라고 이해했고, 그냥 우리가 사용하는 크롬이나 파이어폭스를 생각하니 크게 의문이 들진 않았다.

일단 먼저 브라우저가 무엇인지에 대해서 알아야한다.

브라우저의 기능은 크게 두가지로 정리해볼 수 있었는데,

  1. 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것
  2. HTML과 CSS 명세에 따라 HTML 파일을 해석해서 표시하는 것

결국 정의에서나 기능에서나 우리가 확인해 볼 수 있는 건 요청 받은 내용들을 브라우저 화면에 표시하는 것이 브라우저의 정의이자 주 역할이다.

이것을 렌더링 이라고 하는데, (관련해서 렌더링 엔진 개념이 있는데 이건 또 공부해봐야겠다.)

화면에 출력하는 과정 즉, 렌더링 하는 과정을 알아보았다.

(아래 과정을 읽고 그림을 다시 보면 조금 더 이해가 잘 될 지도?)

① DOM 트리 구축 위한 HTML 파싱

  • 먼저 브라우저가 렌더링할 문서를 HTML과 CSS로 나눠서 읽는다.

  • 이때, HTML과 CSS는 단순 텍스트이므로 연산 및 관리가 가능하도록 각각을 파싱하는데,

  • HTML 문서를 파싱하여 태그들을 DOM으로 변환시킨다.

(*DOM은 문서 객체 모델이라고 해서 브라우저에서 HTML을 다루기 위해 구성 요소(태그)들을 객체로 구조화 하여 나타낸 것이다.

DOM | PoiemaWeb위 그림과 같이 HTML 태그들을 트리의 형태로 구조화시킨 것이다. )

  • 외부 CSS 파일과 함께 포함된 스타일 요소도 같이 파싱한다.(CSSOM)
  • 이렇게 CSS와 HTML을 파싱하여 브라우저에서 사용할 수 있는 객체 모델로 만드는 과정이다.

② 렌더 트리 구축

  • 1단계에서 각각을 파싱하여 트리로 만들었다면 이 둘을 연결하여 표시해야 할 순서로 내용을 그려낼 수 있도록 하기 위해 렌더 트리를 생성해준다.
  • 렌더트리에는 스타일 정보가 설정되어 있어서 실제 화면에 표현되는 노드들로만 구성이 되어있다(예를들어 display: none; 속성의 노드는 렌더 트리를 만드는 과정에서 제외된다.)

③ 렌더 트리 배치

  • 렌더 트리 생성이 끝나면 브라우저가 각 노드들을 표시할 정확한 위치와 크기를 계산하며 배치 작작업을 한다.
  • Layout 설계를 한다고 생각하면 될 것 같다.

④ 렌더 트리 그리기

  • Layout에 따라, 렌더 트리를 사용해 요소들을 실제 화면에 그린다.

내가 읽고 이해한 정도로만 정리한 것이다.

간단하게 정리해보면 DOM, CSSOM 생성 > 렌더 트리 생성 > 렌터 트리에 따라 그리기

혹시라도 이상한 부분이 있다면 읽고 계신 분의 생각이 맞다.

2. Virtual DOM

가상화 DOM ??

결국 DOM이라는게 뭔지 알기 위해 렌더링 과정을 공부했다.

요즘 웹페이지는 조건에 따라 바뀌는 것들이 많다. 예를 들어서, 버튼을 누르면 해당 버튼의 색이 바뀐다던지 말이다.

그렇다면, 위 예시에서 버튼을 눌렀을 때 요청이 가고 색상이 입혀진 버튼으로 변경된 HTML문서의 응답이 오면 변경 사항이 반영된 DOM을 다시 구축하여 전체를 화면에 다시 출력하는 렌더링 과정을 거치게 된다.
(이를 리렌더링 이라고 한다.)

즉, node가 변경 될 때 마다 위의 렌더링 과정이 새롭게 이루어지기 때문에 작은 것 하나만 바뀌어도 굳이굳이 다른 것들 까지 렌더링을 해서 효율성이 떨어진다는 것 같다.

그래서, 이때 등장하는 것이 Virtual DOM이라고 하는데,,

  • Virtual DOM은 가상화된 DOM으로써 가상화 시킨 DOM을 메모리에 만들어 놓는다.

  • 그리고 데이터가 업데이트 되면, Virtual DOM에 리렌더링을 하고

  • 이전 Virtual DOM에 있던 내용과 현재의 내용을 비교하여

  • 바뀐 부분만 실제 DOM에 적용한다.

즉, 메모리에 가상화된 DOM을 올려두고 변경 전 후의 상태를 비교한 뒤 최소한의 내용만 반영하는 것이다.

이 설명만 보면 느낌이 확 오진 않았는데 다른 여러 글들의 예시를 보니 좀 알 것 같았다.
(다른 글들의 예시는 좀 더 자세한데 나는 그냥 간단하게만 했다.)

...
<div id="root">
    ...
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>    
</div>

위와 같이 구조가 잡혀있을 때 li태그 안의 내용을 바꾸려고한다.

📍 비효율적인 방법

const root = document.querySelector('#root')
const liTagList = root.querySelectorAll('li')

liTagList[0].textContent = '4' // 렌더링 발생 (1)
liTagList[0].textContent = '5' // 렌더링 발생 (2)
liTagList[0].textContent = '6' // 렌더링 발생 (3)

이렇게 뭔가 변경이 있을 때 마다 DOM에 접근하여 수정을 하고 렌더링을 하는 과정이

총 3번 발생이 된다.

📍 Virtual DOM을 통하면?

const root = document.querySelector('#root')
const virtualDOM = document.createElement('ul') // 태그 새로 생성

// 각각의 li 태그 생성
const liFour = document.createElement('li')
liFour.textContent = '4'

const liFive = document.createElement('li')
liFive.textContent = '5'

const liSix = document.createElement('li')
liSix.textContent = '6'

virtualDOM.appendChild(liFour)
virtualDOM.appendChild(liFive)
virtualDOM.appendChild(liSix)

// 기존의 ul 태그를 새로 생성한 태그로 교체 하면서 렌더링 (1)
root.replaceChild(virtualDOM, root.querySelector('ul'))

li 태그를 각각 렌더링을 하는 게 아니라 변경사항을 virtual DOM에 가지고 와서 ul태그 하나를 통째로

바꾸고 1번의 렌더링으로 끝낸다.

(여기서 virtualDOM은 실제 virtual DOM이 아니라 그냥 하나의 변수이다. 그냥 이해를 위해서 같은 이름을 사용했다.)

끝으로

virtual DOM을 공부하려고 렌더링, DOM, 브라우저를 간단하게 살펴보면서 공부했다.

공부를 하면서 항상 느끼는 거지만 뭔가 공부를 시작하면 점점 더 할게 많아지는 것 같다.

이해할 수 있는 선에서만 공부를 했지만, 렌더링에 있어 HTML, CSS를 파싱하는 방법이라던지 렌더링 엔진, virtual DOM에서 변경사항을 비교하는 알고리즘 등 알아가야 할 것들이 쏟아져 나왔다.

그래도 virtual DOM이 무엇인지 학습하는 소기의 목적은 달성해서 만족스럽고...

또 시간이 되면 새로 접한 개념들을 공부해봐야겠다.

결국 virtual DOM은 훨씬 효율적인 렌더링을 할 수 있게 도와주는 기능!!!

profile
안녕하세요~ 개발을 꿈꾸는 하얀족제비입니다!

0개의 댓글