React Virtual DOM

박정호·2022년 8월 30일
0

React.js

목록 보기
2/6
post-thumbnail
post-custom-banner

🛸 Virtual DOM

  • Virtual DOM을 사용하여 실제 DOM에 접근하여 조작하는 대신, 이를 추상화하여 자바스크립트 객체를 구성하여 사용 (= 실제 DOM의 가벼운 사본)

  • DOM의 상태를 메모리에 저장하고, 변경 전과 변경 후의 상태를 비교한 뒤
    최소한의 내용만 반영 하는 기능 → 성능 향상

  • 가상 DOM은 DOM의 상태를 메모리 위에 계속 올려두고,
    DOM에 변경이 있을 경우 해당 변경을 반영함

가상 DOM(VDOM)은 이상적인 또는 "가상" UI 표현이 메모리에 유지되고 ReactDOM과 같은 라이브러리에 의해 "실제" DOM과 동기화되는 프로그래밍 개념입니다. 이 과정을 조정 이라고 합니다 . (공식문서)

⭐️ 다음과 같은 문제를 해결하기 위해

  • DOM조작에 의한 랜더링이 비효율적인 문제
  • SPA특징으로 DOM 복잡도가 증가함에 따라 최적화 및 유지보수가 더 어려워지는 문제
  • DOM은 트리 구조로 되어 있어서 이해하기 쉽지만, 노드의 수가 많아질 수록 속도가 느려지고, DOM 업데이트에 잦은 오류를 발생키는 문제

DOM을 반복적으로 직접 조작하면 그 만큼 브라우저는 랜더링이 자주 일어나고, 자원 소모가 심해진다.
DOM 자체는 빠르지만, 변화가 일어나면 CSS 연산, 레이아웃 구성, 페이지 리페인트로 시간이 허비된다. 이처럼 DOM을 조작할 때마다 엔진이 웹 페이지를 새로 그리기 때문에 업데이트가 잦으면 성능 저하가 발생. 하지만 DOM을 조작하지 않을 수는 없다.

⭐️ 따라서, 리액트는 Virtual DOM 방식을 사용하여 DOM 업데이트를 추상화함으로써 DOM 처리 횟수를 최소화하고 효율적으로 진행. Virtual DOM을 사용하면 실제 DOM에 접근하여 조작하는 대신, 이를 추상화한 자바스크립트 객체를 구성하여 사용

⭐️ 리액트에서 데이터 변화로 웹 브라우저에 실제 DOM을 업데이트 할 때 거치는 3가지

1. 데이터를 업데이트하면 전체 UI를 Virtual DOM에 리렌더링

2. 이전 Virtual DOM에 있던 내용과 현재 내용을 비교

3. 바뀐 부분만 실제 DOM에 적용

작은 규모의 레이아웃(리플로우)이 여러번 발생하는 것보다 큰 규모의 레이아웃이 한 번 발생하는 것은 성능상의 큰 차이를 나타낸다. 리액트는 위와 같은 얕은 비교와 일괄 돔 업데이트 방식을 이용해 성능 향상을 이끄는 것이다.

물론 리액트의 사용 없이도 코드 최적화를 열심히하면 DOM 성능 저하문제를 해결이 가능하고, 단순 라우팅만하는 정적페이지의 경우 리액트를 사용하지 않는 것이 성능이 나을 수 있다.

🌲 DOM이란?

브라우저에서 다룰 HTML 문서를 파싱하여 객체로 문서 구조를 표현하는 방법이다. 쉽게 말해 DOM은 브라우저와 자바스크립트가 HTML을 이해하기 쉽게 트리 구조로 표현한 객체이다. DOM은 웹 페이지의 객체 지향 표현이고, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM을 수정할 수 있다.

⭐️ DOM은 HTML과 JS를 이어주는 역할

DOM은 HTML Elements, Attributes, CSS styles, Events, Methods 등을 제어할 수 있는 표준 인터페이스를 제공한다.

parsing(파싱): 어떤 문장을 분석하거나 문법적 관계를 해석하는 행위

〰 브라우저의 Workflow

⭐️ 렌더링 : 브라우저 로딩 과정 중 스타일 이후의 과정(스타일-> 레이아웃 -> 페인트 -> 합성)을 렌더링이라고 한다.

✏️ DOM Tree 생성
브라우저가 HTML 을 전달받으면, 브라우저의 렌더 엔진이 이를 파싱하고 DOM 노드(Node) 로 이뤄진 트리를 만들어요. 각 노드는 각 HTML 엘리먼트들과 연관.

✏️ Render Tree 생성
외부 CSS 파일과 각 엘리먼트의 inline 스타일을 파싱한다. 그리고 스타일 정보를 사용하여 DOM 트리에 따라 새로운 트리, 렌더트리를 만든다.

✏️ Render Tree 생성
Webkit 에서는 노드의 스타일을 처리하는 과정을 ‘attachment’ 라고 부른다. DOM 트리의 모든 노드들은 ‘attach’ 라는 메소드가 있고, 이 메소드는 스타일 정보를 계산해서 객체형태로 반환한다.

이 과정은 동기적(synchronous) 작업이고 DOM 트리에 새로운 노드가 추가되면 그 노드의 attach 메소드가 실행된다.

렌더 트리를 만드는 과정에선, 각 요소들의 스타일이 계산되고, 또 이 계산되는 과정에서 다른 요소들의 스타일 속성들을 참조한다.

✏️ Layout(= reflow)
렌더 트리가 다 만들어지고 나면, 레이아웃 과정을 거고 각 노드들은 스크린의 좌표가 주어지고, 정확히 어디에 나타나야 할 지 위치가 주어진다

✏️ Painting
그 다음 작업은 렌더링 된 요소들에 색을 입히는 과정. 트리의 각 노드들을 거쳐가면서 paint() 메소드를 호출. 그리고 스크린에 원하는 정보가 나타난다.

출처: https://velopert.com/3236

👍 정리

✏️ 리액트의 virtual DOM은 실제 DOM과 같은 내용을 담고 있는 복사본이다. 그리고 이 복사본은 JS 객체 형태로 메모리 상에 저장되어있다.

✏️ 리액트는 항상 두개의 virtual DOM을 가지고 있다. 첫번째는 virtual DOM은 이전의 내용을 담고 있고, 두번째 virtual DOM은 변경 이후에 보여질 내용을 담고 있다.

✏️ 변경된 내용이 화면에 새롭게 그려지기 이전, 곧 실제 DOM이 변경되기 이전에 리액트는 두개의 virtual DOM을 비교해서 정확히 어떤 부분이 바뀌었는지 효율적으로 비교하여 파악한다. 그리고 이러한 과정을 Diffing이라고 부른다.

✏️ Diffing을 통해서 변경된 부분들을 파악한 후에 리액트는 Batch Update를 수행함으로써 실제 DOM에 한번에 적용시킨다. 그리고 이러한 과정을 Reconsiliation(재조정)이라고 한다.

참조:

쉬운설명: https://www.youtube.com/watch?v=gc-kXt0tjTM

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)
post-custom-banner

0개의 댓글