본문 바로가기

React

React - Virtual DOM

  • HTML의 Dom Tree를 추상화한 것.
  • React는 state가 변경되면 새로 렌더링을 하는데, 실제 Dom Tree에 데이터를 렌더링 하기전에 먼저 virtual dom에 렌더링을 한 이후 변경된 부분을 확인하고 그 부분만 새로 교체하여 렌더링하기때문에 효율적이다.
  • React만 가지고 있는 것은 아니고, React와 비슷한 언어들은 대부분 가지고있다고한다.
  • 하지만 모던 브라우저(크롬, 사파리 등) 들은 DOM이 노드를 사용하지 않고 자바스크립트와 동일한 메모리모델을 쓰기때문에, 리엑트와 동일하게 바뀐것이 없다면 추가작업을 하지 않기때문에 더이상 큰 성능문제는 없다고한다.

dom과 virtual dom의 차이

Dom

  • Document Object Model
  • 브라우저의 렌더링 엔진에 의해 HTML문서를 파싱하고, HTML문서 안의 태그들을 브라우저가 이해할 수 있는 형태인 DOM을 생성한다.
  • 따라서 HTML마크업과 DOM은 1:1관계를 맺게된다.

Virtual DOM

  • Virtual DOM은 DOM을 모방하는 형태로 메모리상에서만 존재하는 가상의 DOM이다.
  • DOM에 변화가 생길 경우, 새로 렌더링을 해야하는데 모든 노드들을 처음부터 다시 그리면 소모적인 렌더링이 발생한다.
  • 그래서 Virtual DOM을 한 번 거쳐 미리 처리하고 저장한 후 실제 DOM에 업데이트할 수 있게 해준다.
  • 메모리상에서만 동작하기때문에 훨씬 더 빠르게 동작되고, 변경사항만을 묶어 한 번만 렌더링을 실행시키므로 효율적이다.
  • dom fragment를 관리하는 과정을 자동화/추상화해준다.
  • 변경사항을 확인할 때에는 diffing알고리즘을 사용하는데 이 알고리즘은 아래와 같이 동작한다.

diffing 알고리즘

  • React Element의 속성값만 변한경우 -> 속성값만 업데이트
  • React Element의 태그 또는 컴포넌트에서 변화를 감지 -> 해당 노드를 포함한 모든 하위노드를 unmount한 후, 새로운 virtual dom으로 대체

dom fragment

  • virtual dom과 같이 메모리상에서만 존재하는 객체이다.
  • dom fragment를 수동으로 조작하여 DOM의 연산횟수를 줄이는 것이 가능하다.
  • 하지만 일일이 DOM의 업데이트여부를 확인하고 수정해줘야하므로 복잡한 어플리케이션에서 dom fragment를 직접 관리하는 것은 거의 불가능한 일이다.
  • 아래와같이 fragment객체를 만들어서 한 번만 렌더링되게 할 수 있다고한다.
var list = document.createElement('ul');
var numbers = ['one', 'two', 'three'];

var frag = new DocumentFragment()

numbers.forEach(function (num) {
	var li = document.createElement('li');
	li.innerText = num;
	frag.appendChild(li);
});

list.appendChild(frag);

Virtual DOM 의 장점

  1. 개발자가 직접 Dom 노드를 신경쓸 필요가 없기때문에 단순하고 깔끔한 코드를 작성할 있다.
  2. 변경사항을 리액트가 적당히 모아서 처리한다.
    리액트는 버츄얼돔이 바뀔때마다 브라우저에 바로 전달하지않고 적당히 모아뒀다가 브라우저에 전달한다.
    그래서 복잡한 페이지에서도 한정된 브라우저 자원을 효율적으로 활용할 있다. 변경사항을 효율적으로 처리할 있다.

렌더링 과정

기존 브라우저의 렌더링 과정

(https://develocal.tistory.com/86)

더보기

렌더링 과정

6. HTML 파싱

  • 렌더링 엔진은 받은 HTML 문서를 파싱하여 웹 페이지의 구조를 이해한다.
  • 이 과정에서 HTML 요소, 태그, 속성 등을 해석하고, "콘텐츠 트리" 내부에서 태그를 DOM노드로 변환한다.

7. Render Tree 구축

  • 브라우저는 파싱된 HTML과 CSS 정보를 결합하여 렌더링 트리를 생성한다.
  • 렌더링 트리는 화면에 표시될 요소의 계층 구조를 나타낸다.
  • 색상 또는 면적과 같은 시각적 속성이 있는 사각형을 포함하고 있는데 정해진 순서대로 화면에 표시된다.

8. 레이아웃 및 페인트

  • 브라우저는 렌더링 트리를 기반으로 각 요소의 크기와 위치를 계산하고 화면에 표시한다.
  • UI백엔드에서 렌더트리와 각 노드를 가로지르며 형상을 만들어낸다.
  • 렌더링 엔진은 좀 더 나은 사용자 경험을 위해 모든 HTML을 파싱할 때 까지 기다리지 않고 레이아웃과 페인트를 시작한다.
  • 따라서 전송을 기다리며 이미 받은 내용의 일부를 먼저 화면에 표시한다.

 



9. 자바스크립트 실행

  • 웹 페이지에 포함된 JavaScript 코드가 실행된다.
  • 이를 통해 동적인 기능을 추가하거나 상호작용을 가능하게 한다.

10. 이벤트 처리

  • 브라우저는 사용자의 입력 및 이벤트(마우스 클릭, 키보드 입력 등)를 감지하고 처리한다.
  • 이벤트 처리기를 사용하여 웹 페이지의 동작을 제어하고 사용자와 상호작용한다.

11. 통신

  • 웹 페이지가 추가적인 데이터를 필요로 할 때, 브라우저는 서버와 통신하여 데이터를 요청하고 응답을 받는다.
  • 이를 통해 웹 페이지는 실시간 업데이트 및 동적 콘텐츠를 제공할 수 있다.

12. 캐싱

  • 브라우저는 이전에 다운로드한 리소스를 캐시에 저장하여 다음에 같은 리소스를 요청할 때 다시 다운로드하지 않도록 한다.
  • 이로써 웹 페이지 로딩 속도를 향상시킬 수 있다.

13. 보안

  • 브라우저는 웹 페이지의 보안을 강화하기 위해 다양한 보안 기술과 메커니즘을 사용한다.
  • 예를 들어, HTTPS를 통한 데이터 암호화, 동일 출처 정책(Same Origin Policy)를 통한 보안 제한 등이 있다.

14. 웹 페이지 표시

  • 최종적으로 브라우저는 렌더링된 웹 페이지를 화면에 표시하고 사용자에게 보여준다.

React의 렌더링 과정

1. render 단계

  • React.createElement로 생성

2. reconciliation 단계

  • 이전 Elements와 새로 생성된 elements 비교

3. commit 단계

  • 바뀐 데이터가 있을 경우, DOM Update

결론

브라우저의 렌더링과정을 꽤 길고 복잡한데, 변경이 일어날 때 마다 작업을 하는 것은 비효율적이기때문에, virtual dom을 사용해서 변화가 생겼을 때만, 변화된 부분만 모아뒀다가 한번에 적용하기때문에 효율적이다.

 

 

 

 

참조

https://callmedevmomo.medium.com/virtual-dom-react-%ED%95%B5%EC%8B%AC%EC%A0%95%EB%A6%AC-bfbfcecc4fbb

https://velog.io/@hyerin0930/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95%EA%B3%BC-React%EC%9D%98-Virtual-DOM

https://velopert.com/3236

https://velog.io/@ooooorobo/Virtual-DOM%EC%9D%84-%EC%93%B0%EB%A9%B4-%EC%99%9C-%EC%A2%8B%EC%9D%84%EA%B9%8C

https://seonghui.github.io/TIL/docs/etc/virtual-dom.html