View

[Web] Virtual DOM이란?

산누 2022. 12. 11. 22:20

브라우저의 동작

브라우저 렌더링 과정

1. DOM tree 생성 : 렌더 엔진이 HTML코드를 읽고 파싱하여 DOM 노드로 이루어진 트리 생성

DOM이란? Document Object Model의 약자로 DOM은 html, xml, CSS 등을 트리 구조로 인식하고 데이터를 객체로 간주하고 관리한다.


2. render tree 생성 : css 파일이나 html에 인라인으로 작성된 스타일 코드를 파싱하여 css DOM을 구성한다.

  • DOM + CSSOM = 렌더 트리를 생성 (문서에 시각적인 구조를 나타냄)

3. Layout(reflow) : 뷰포트 내에서 생성된 render tree의 각 노드들의 스크린에서의 좌표에 따라 위치 결정
4. Paint(repaint) : 실제 화면에 그리기

렌더링이란? HTML, CSS, 자바스크립트 등 개발자가 작성한 문서가 브라우저에서 출력되는 과정을 말한다.

 

DOM 조작의 비효율성

여기서 문제는 어떤 인터랙션에의해 DOM에 변화가 발생하면 render tree가 그때마다 재생성된다는 것이다.변화가 발생하면 모든 요소들의 스타일을 다시 계산하고 reflow 과정을 거치고 다시 repaint하는 과정까지 반복한다.
예를 들어 유저가 어떤 포스트에 좋아요를 누르거나 담아둔 장바구니 목록에서 상품을 하나 삭제하거나, 댓글을 남기면 전체 노드들이 다시 그려지게되는 것이다. DOM을 조작하는 소모적인 비용이 발생함.

무조건 Virtual DOM? 🤔
정보 제공만 하는 웹페이지라면 인터랙션이 발생하지 않기 때문에 일반 DOM의 성능이 더 좋을 수도 있다.
하지만, SPA로 제작된 큰 규모의 웹 페이지에서는 Virtual DOM을 사용해서 브라우저의 연산 양을 줄여 성능을 개선할 수 있다.

 

Virtual DOM의 등장

페이지를 서버가 아닌 브라우저에서 관리

최근에는 SPA(Single Page Application)을 많이 사용하면서 DOM tree를 즉각적으로 많이 변경할 일이 생겨났다. 전체 페이지를 서버에서 매번 보내주는 것이 아니라, 브라우저단에서 자바스크립트가 관리하기 때문에 DOM 조작을 더욱 더 효율적으로 할 수 있게끔 최적화가 필요해졌다. 그래서 등장한 것이 Virtual DOM이다.

Virtual DOM이란?

Virtual DOM은 기존 DOM의 복사본이자 HTML DOM의 추상화 버전이다.
실제 DOM object와 같은 속성(class 등)들을 가지고 있지만, 실제 DOM이 갖고 있는 api(getElementById 등)는 갖고 있지 않다.

  1. 데이터가 변경되면 전체 UI는 virtual DOM에 렌더링된다.
  2. 이전 virtual DOM에 있던 내용과 업데이트 후의 내용을 비교하여 바뀐 부분만 실제 DOM에 적용시킨다.

즉, virtual DOM에 변경사항이 반영되면 원본 DOM에 필요한 변화만 반영되어서 전체 real DOM을 바꾸지 않고도 필요한 UI의 업데이트를 적용할 수 있다.

 

Virtual DOM의 동작 원리

Virtual DOM은 HTML 객채에 기반한 자바스크립트 객체로 표현할 수 있다.

  • JavaScript 객체로 표현
  • 실제 DOM이 아닌 메모리 상에서 동작 (훨씬 빠름)
  • 실제 렌더링이 되지않기때문에 연산 비용 최소화 (모든 변화를 하나로 묶어서 딱 한 번만 실행)

사실 Virtual DOM이 하는 건 DOM fragment의 변화를 묶어서 적용한 다음 기존 DOM에 던져주는 과정을 자동화, 추상화한 것에 불과

 

React의 Virtual DOM

React는 Virtual DOM을 이용하는 대표적인 자바스크립트 라이브러리로
React에서 Virtual DOM을 UI의 가상적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 실제 DOM과 동기화하는 프로그램의 개념이다 라고 설명하고 있다. 그리고 이 과정을 재조정이라고 부른다.

 

JSX

JSX(JavaScript XML)는 Javascript에 XML을 추가한 확장 문법이다. JSX를 컴포넌트에서 리턴 시키면 바벨은 JSX를 React.createElement() 호출로 컴파일한다. 실제 바벨에서 변환을 시켜보면 React element 객체를 리턴하는 하는 것을 확인할 수 있다.


React elements는 DOM 요소의 가상 버전으로 가볍고 상태를 가지지 않으며, 불변성을 유지한다. 이 불변성 덕분에 비교하고 업데이트 하는 게 쉬워짐. React elements는 reactDOM의 render에 의해서 비로소 실제 DOM 요소가 된다. React는 이 객체를 읽어들이고 이를 사용해서 DOM을 구성하고 항상 최신상태로 유지함.

하지만 앞서 말했듯 이 react elements는 변경이 불가하기 때문에 한번 요소가 만들었다면 데이터가 변해도 그 자식이나 속성을 맘대로 변경할 수 없다. UI를 업데이트할 수 있는 유일한 방법은 새로운 요소를 만들어 ReactDom.render()로 전송하는 것 뿐이다.

 

diffing 알고리즘

모든 React DOM object는 그에 대응하는 virtual DOM object가 있다. 그리고 virtual DOM object는 그 DOM object 하나하나에 매핑된다. 데이터가 업데이트 되면 바뀐 데이터를 바탕으로 React.createElement()를 통해 JSX element를 렌더링한다. 이때 모든 각각의 virtual DOM object가 업데이트된다. virtual DOM이 업데이트되면 React는 Virtual DOM을 업데이트 이전에 virtual DOM 스냅샷과 비교하여 정확히 어떤 virtual DOM이 바뀌었는지 검사한다. 이 과정을 "diffing" 알고리즘이라고 한다.

  • element의 속성 값만 변한 경우 ➡️ 속성 값만 업데이트
  • element의 태그 또는 컴포넌트가 변경된 경우 ➡️ 해당 노드를 포함한 하위 모든 노드를 unmount(제거) 후 새로운 virtual DOM으로 대체

 

 

728x90
Share Link
reply
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31