Virtual DOM

‍김다솔·2021년 6월 27일
0

브라우저 렌더링 과정

1. DOM 트리 생성

렌더 엔진이 HTML을 파싱하여 DOM 노드로 이루어진 트리 생성

2. render 트리 생성

  • css 파일과 inline 스타일을 파싱하여 DOM + CSSOM = render 트리 생성
  • 시각적인 구조를 나타냄

3. Layout (Reflow)

뷰포트 내에 생성된 render 트리의 각 노드들이 스크린에서의 좌표에 따라 위치 결정

4. Paint (Repaint)

실제로 화면에 그리기

문제

  • 어떤 인터랙션으로 DOM에 변화가 발생하면 render 트리가 그때마다 재생성됨
  • 변화가 발생하면 모든 요소들의 스타일을 다시 계산하고 똑같은 과정을 반복해야 함
  • 최근에는 SPA에서 DOM 트리를 즉각적으로 많이 변경하는 경우가 생김
  • 전체 페이지를 서버에서 매번 보내주는 것이 아니라 브라우저단에서 자바스크립트가 관리하기 때문에 DOM 조작을 더 효율적으로 할 수 있게끔 최적화가 필요하여 생긴 Virtual DOM

Virtual DOM

  • 기존 DOM의 친구이자 복사본
  • HTML DOM의 추상화 버전
  • 실제 DOM 오브젝트와 같은 속성을 갖고 있지만, 실제 DOM이 갖고 있는 API는 갖고 있지 않음
  • 데이터가 변경되면 전체 UI는 Virtual DOM에 렌더링 됨
  • 이전 Virtual DOM에 있던 내용과 업데이트 후의 내용을 비교하여 바뀐 부분만 실제 DOM에 적용시킴
  • 즉, Virtual DOM에 변경사항이 반영되면 원본 DOM에 필요한 변화만 반영되어 전체 real DOM을 바꾸지 않고 업데이트 가능
  • Virtual DOM은 HTML 객체에 기반한 자바스크립트 객체로 표현할 수 있음
  • 위는 DOM이 아닌 메모리 상에서 동작하여 더 빠름
  • Virtual DOM 트리는 실제 렌더링 되지 않기 때문에 연산 비용이 적음
  • 즉, 모든 변화를 하나로 묶어서 딱 한 번만 실행시키기 때문에 실제 DOM 리렌더링에 비해 효율적임
  • DOM fragment의 변화를 묶어서 적용한 다음, 기존 DOM에 던져주는 과
  • Virtual DOM은 이 과정을 자동화, 추상화해 놓은 것에 불과함

React와 Virtual DOM

재조정

UI의 가상적인 표현을 메모리에 저장하고 React DOM과 같은 라이브러리에 의해 실제 DOM과 동기화

JSX

  • 각 컴포넌트에서 return 되는 element를 JSX문법으로 작성
  • 자바스크립트 확장 문법
  • 리턴시키면 babel은 JSX를 React.createElement() 호출하여 컴파일 함
  • react element는 내부적으로 객체로 표현될 수 있음
  • Virtual DOM 객체 구성형태와 비슷함
  • light & immutable & stateless : 상태를 가지지 않고, 불변하며, 상태를 가지지 않음
  • 불변성 덕분에 비교하고 업데이트하기 쉬워짐

  • react element는 ReactDOM의 render에 의해서 실제 DOM 요소가 됨
  • React는 이를 이용하여 DOM을 구성하고 항상 최신 상태로 유지
  • react element는 불변하므로 한번 요소를 만들면 데이터가 변해도 그 자식이나 속성을 맘대로 변경할 수 없음
  • 각 element는 해당 순간의 UI를 스냅샷 형태로 보여줄 뿐임
  • 따라서 UI를 업데이트할 수 있는 유일한 방법은 새로운 요소를 만들어 ReactDom.render()로 전송하는 것 뿐임
  • 모든 React DOM 오브젝트는 그에 대응하는 Virtual DOM 오브젝트가 있음
  • 그 Virtual DOM 오브젝트는 DOM 오브젝트 하나하나에 매핑됨

  • 데이터가 업데이트 되면 바뀐 데이터를 바탕으로 React.createElement()를 통해 JSX element를 렌더링함
  • 이때 각각 모든 Virtual DOM 오브젝트가 빠르게 업데이트 되어 비용이 많이 들지 않음

Diffing 알고리즘

  • Virtual DOM이 업데이트 되면 React는 Virtual DOM을 업데이트 이전의 Virtual DOM 스냅샷과 비교하여 어떤 Virtual DOM이 바뀌었는지 확인함
  • element의 속성 값만 변한 경우 속성 값만 업데이트하고, 태그나 컴포넌트가 변경된 경우라면 해당 노드를 포함한 모든 하위 노드를 unmount, 제거한 뒤에 새로운 Virtual DOM으로 대체
  • 업데이트 마무리된 이후에 딱 한 번 실제 DOM에 이 결과를 업데이트 함

1. 전체 Virtual DOM이 업데이트 됨

+ 버튼을 누르면 이미지 태그 요소가 하나 추가되고 바뀐 데이터에 따라 전체 Virtual DOM이 업데이트 됨

2. Virtual DOM을 업데이트 이전의 시점과 비교

3. 실제로 바뀐 부분만 real DOM에서 바꿈

새로운 이미지 태그만 real DOM 트리에 렌더링 됨

4. real DOM에서의 변화가 스크린에 그려짐

전체 DOM 트리가 처음부터 다시 그려지는 것이 아니라 Virtual DOM의 도움을 받아 이미지 태그가 하나 추가된 부분만 새로 그려지게 됨

Virtual DOM이 DOM보다 무조건 빠를까?

  • NO, 정보 제공만 하는 웹페이지라면 인터렉션이 발생하지 않아(DOM 트리 변화가 발생하지 않음) 일반 DOM의 성능이 더 좋을 수도 있음
  • SPA로 제작된 큰 규모의 웹 페이지는 Virtual DOM을 사용해서 브라우저의 연산 양을 줄여 성능을 개선할 수 있음
profile
💻🎧⚽

0개의 댓글