Virtual DOM (with React)

Ocean·2023년 5월 17일
0

fe🔥

목록 보기
1/3

React를 배우면서 처음 나오는 개념들 중 하나는 Virtual DOM(가상 DOM)이다. 가상 DOM에 대해 찾아보다가 "가상 DOM이 실제 DOM보다 성능이 좋다"라는 주장과 "가상 DOM을 사용하는 것이 실제 DOM을 조작하는 것보다 빠르다는 것은 오해다"라는 주장을 모두 볼 수 있어 혼란스러웠다.

글을 찾아보면 찾아볼수록 머릿속엔 다음과 같은 질문들이 쌓였다.

  • virtual DOM은 도대체 어떻게 동작하는 것인가?
  • virtual DOM과 실제 DOM 조작 중 어떤 것이 더 성능이 좋을까?
  • React는 왜 virtual DOM을 선택했을까?

이 글은 위의 질문들을 해결하기 위해 읽었던 수많은 자료 중 나의 이해를 도왔던 정보들의 모음집이다.

먼저 Virtual DOM의 의미를 알아보자.

1. DOM?

"virtual DOM"이라는 말은 DOM을 가상으로 만들어냈다는 의미이다. 여기서 DOM은 무엇인가?

DOM이란?

DOM(Document Object Model, 문서 객체 모델)은 HTML/XML 문서에 접근하기 위한 인터페이스이다. 브라우저는 HTML 문서를 파싱하여 사용자에게 시각화해 준다. 이때 브라우저가 띄워주는 HTML 문서에 어떤 동적 처리를 해주고 싶을 때, 이를 도와주는 인터페이스가 DOM이다.

DOM이 필요한 이유

자바스크립트로 직접 HTML을 동적으로 바꾸는데에는 한계가 있기 때문에, JS가 조작하기 편하게 DOM이라는 형태로 바꾸어 놓은 것이다. JS가 HTML을 조작해야 하는 이유는, 더 다양하고 복잡한 인터렉션을 만들고 화면을 구현하기 위해서 필요하다.

DOM이 만들어지는 과정

브라우저가 DOM Tree를 생성하는 과정

  1. 네트워크를 통해서 HTML 문서를 불러온다. (raw byte)
  2. raw byte의 데이터를 characterize 한다.
  3. characterize화 된 값을 tokenize화 한다.
  4. tokenize화 된 값을 Nodes로 바꿔준다.
  5. Nodes를 기반으로 DOM Tree를 생성한다.

DOM은 어쩌다 만들어졌을까? (DOM의 역사...)

역사적으로 DOM의 탄생 배경은 "브라우저 전쟁"과 관련이 있다. 브라우저 전쟁이란, 마이크로소프터와 넷스케이프 내비게이터가 자신이 만든 브라우저의 점유율을 높이기 위해 벌인 전쟁이다. 그들은 자신의 브라우저의 사용성을 어떻게든 높이기 위한 전쟁을 벌었고, 그 과정에서 사용된 기술이 JavaScript, JScript이다. 이런 기술들은 화면에서 더 다양한 상호작용을 할 수 있도록 만들어주었다.

이전과는 다르게 웹페이지에서 더 많은 상호작용이 일어나야하고, 더 많은 조작이 가능하도록 만들어져야 하기 때문에 탄생한 것이 바로 DOM이다.

한 마디로 DOM은 JS가 HTML을 쉽게 조작하도록 만들어진 객체이고, virtual DOM은 이를 가상으로 만들었다는 것이다. 왜 DOM을 가상으로 만들어야 했을까?


🫧 2. Virtual DOM?

Virtual DOM의 기본 원리

  1. 실제 DOM과 같은 내용을 담고 있는 복사본을 객체 형태로 메모리 안에 저장한다. → 가상 DOM 생성
  2. 변화가 생길 때마다 새로운 내용이 담긴 가상 DOM 새로 생성한다.
  3. 이전 버전의 가상 DOM과 새로운 버전의 가상 DOM을 비교해서 어떤 element가 변했는지 찾는다. (diffing)
  4. 발견한 차이점을 실제 DOM에 적용한다.

결국 virtual DOM은 하나의 가상 레이어라고 할 수 있다. 변경사항을 DOM에 바로 반영하지 않고 그 변경사항들을 모아뒀다가, 한 번에 DOM에 적용한다. 그러면 DOM은 업데이트를 딱 한 번만 하면 되고, 렌더도 한 번만 하면 된다.

Virtual DOM을 사용하게 된 또 다른 배경

그건 바로 변경을 감지하는 방법이다.

변화를 감지하는 2가지 방법

1. dirty checking
dirty checking 방법은 node tree를 재귀적으로 계속 순회하면서 어떤 노드에 변화가 생겼는지 인식하는 방법이다. 만약 변화가 생긴 노드를 발견하면 그 노드만 리렌더링을 시켜주면 되는 방식이다. 이 방법은 augular.js가 사용하던 방법인데, 이는 변화가 없을 때도 재귀적으로 노드를 탐색함으로써 불필요한 비용이 발생한다.

2. observable
observable은 변화가 생긴 노드가 관찰자에게 알림을 보내주는 방식이다. React의 경우 state에 변화가 생겼을 때, React에게 리렌더링을 해줘야한다는 것을 알려주는 방식으로 이루어진다. React는 알림을 받으면 렌더링을 시킨다. 이는 변화가 생기기 전까지는 아무일도 하지 않아도 된다.

Observable의 문제점

observable의 문제점은 변화에 대한 알림을 받으면 전체를 리렌더링 한다는 것이다.

Facebook에서는 프론트엔드 MVC 패턴을 사용하고 있었다. 당시 페이스북 메시지가 오지 않았는데 메시지가 와 있다고 뜨는 심각한 버그가 있었고, 이들은 그 버그를 해결하지 못 했다.

데이터 흐름을 파악하고 버그를 체크하는데 지친 그들은 아예 새로운 발상을 하게 된다.

🧑‍💻 : 그냥 데이터가 바뀌면 싹 다 다시 그리면 안 되나..

DOM에 변경사항을 조작해서 넣지 말고, 그냥 데이터가 바뀔 때마다 전부 다 다시 그려버리면 버그가 생기지 않을 거란 아이디어에서 시작되었다.

하지만, 전체를 렌더링시키는 것은 엄청난 reflow-repaint 비용을 발생시킨다. 이때 사용할 수 있는 게 바로 Virtual DOM이다!!

Virtual DOM을 사용하다

가상 DOM은 위에서 말한 것과 같이 메모리 상에 존재하는 하나의 객체이다. 이제 React는 state가 변했다는 알림을 받으면 전부 다 가상 DOM에 새로 그리고, 기존 DOM과 비교해서 변경된 부분만 DOM에 한 번에 보낸다.

즉, 실제 DOM을 렌더링 시켜주는 것이 아니라, 가상 DOM을 렌더링 시킨다. 실제 DOM을 렌더링하는 것은 브라우저를 렌더링 하는 것이고, 가상 DOM을 새로 그리는 것은 객체를 새로 만드는 것이다.

브라우저를 새롭게 렌더링 시키는 비용보다, 객체를 새로 만드는 비용이 훨씬 더 저렴하다. 그래서 React는 가상 DOM이라는 새로운 객체를 메모리상에 만드는 방식을 선택했다. 상당히 도전적인 아이디어였지만 결국 React는 virtual DOM 사용을 성공했다. React를 이용하면 데이터 흐름과 DOM 차이에 대한 버그가 발생하지 않았고, 코드를 선언적으로 작성할 수 있었다.

흔한 오해

"대부분의 상황에서 Virtual DOM은 빠르지 않다."

  • 가상 DOM을 조작하고 → DOM을 조작하는 것
  • DOM을 조작하는 것

위와 같이 가상 DOM을 사용한다는 것은 하나의 레이어를 더 거쳐가는 동작이기 때문에, DOM 조작이 아주 많지 않다면 DOM을 직접 조작하는 것보다 느리다. 다만, React와 같이 DOM 조작이 빈번하게 일어날 경우 (변화가 발생하면 전체를 다시 그림), 가상 DOM을 이용해서 업데이트를 모아 실제 DOM에 적용하는 것이 효율적이다.

3. 정리

Q1. virtual DOM은 도대체 어떻게 동작하는 것인가?

  1. 실제 DOM의 복사본을 객체 형태로 메모리 안에 저장한다.
  2. 변화가 생기면 그 변화를 적용시킨 가상 DOM을 새로 생성한다.
  3. 이 두 가상 DOM을 비교한다.
  4. 발견한 차이점을 실제 DOM에 적용한다.

Q2. virtual DOM과 실제 DOM 조작 중 어떤 것이 더 성능이 좋을까?

DOM 조작이 아주 많지 않다면 실제 DOM을 조작하는 것이 더 빠르다. 하지만 React와 같이 빈번한 DOM 조작이 많이 발생하는 경우 virtual DOM을 사용하는 것이 더 효율적이다.

Q3. React는 왜 virtual DOM을 선택했을까?

React는 state가 변경되면 전체를 다시 렌더링한다. 이 때 실제 DOM을 바로 조작하는 것은 너무 큰 부하가 든다. 때문에 변경사항을 묶어서 업데이트 할 수 있는 가상 DOM을 선택했다.

4. 참고자료

virtual dom이 뭐가 좋은가? (feat.React fiber)

React가 Virtual DOM을 사용하는 이유

Virtual DOM(React) 핵심정리

profile
chick! chick!

0개의 댓글