React와 Virtual DOM

jiyunlee
6 min readSep 18, 2021

--

브라우저의 Workflow

브라우저의 Workflow

DOM Tree : 브라우저가 HTML 을 전달받으면 렌더링 엔진이 이를 파싱하고 DOM Node로 이루어진 트리를 만듭니다.

Render Tree : 외부 CSS 파일과 Inline 스타일을 파싱한 스타일 규칙을 DOM 트리에 적용해 렌더트리를 생성합니다. (Webkit 에서는 스타일을 처리하는 이 과정을 ‘Attachment’ 라고 부릅니다. DOM Node의 ‘attach’ 라는 메소드는 스타일 정보를 계산해 객체형태로 반환합니다. 이 과정은 동기적 작업이며, 노드가 추가되면 attach 메소드가 실행됩니다. 렌더 트리를 만드는 과정에서 각 요소들의 스타일이 계산되고, 다른 요소들의 스타일 속성들을 참조합니다.)

Reflow : 렌더 트리가 다 만들어지고 나면, 각 노드에 스크린의 좌표와 정확한 위치가 주어집니다. (레이아웃)

Painting : 트리의 각 노드들을 거쳐가면서 paint() 메소드를 호출해 스크린에 정보를 노출합니다.

Virtual DOM

DOM에 변화가 발생할 때마다 렌더트리를 재생성하고 레이아웃을 만들고 페인팅을 하는 모든 과정이 반복됩니다. 따라서 직접 DOM을 조작하는 것은 전체적인 프로세스를 비효율적으로 만듭니다.

반면 가상돔은 변화를 실제 DOM 에 적용하기 전에, 이전 가상돔과 새로운 가상돔을 비교하여 최종적인 결과만을 실제 DOM에 전달합니다. 이를 통해 브라우저 내에서 발생하는 연산을 줄여 성능을 개선하는 것입니다.

React의 render() 결과는 실제 DOM Node가 아닌 그 형태를 본딴 “자바스크립트 객체”로 반환됩니다. render()를 통해 생성된 자바스크립트 객체가 가상 돔을 구성하는 것입니다. 간단한 코드를 보며 이해해보겠습니다.

<div id="parent">
<p class="child1">child</p>
<p class="child2">child</p>
</div>

React는 위와 같이 작성된 DOM Node를 아래와 같이 type, props, children을 가진 자바스크립트 객체로 메모리에 저장합니다.

{
type: 'div',
props: {
id: 'parent'
},
children: [
{ type: 'p', props: { id: 'child1' }, 'child' }
{ type: 'p', props: { id: 'child1' }, 'child' }
]
}

브라우저는 이를 다음과 같은 함수로 이해합니다.

React.createElement('div', { id: 'parent' },
React.createElement('p', { class: 'child1' }, 'child')
React.createElement('p', { class: 'child2' }, 'child')
);

그런데 가상돔의 문제는 가독성이 매우 떨어진다는 점입니다. 이를 해결하기 위해 JSX가 등장했습니다. JSX를 이용하기 위해서는 Babel이 필요하며, 이를 다시 브라우저에 렌더링하기 위해서 ES5 문법으로 변환하는 트랜스파일링 과정이 요구됩니다.

+React Element & React Component & JSX

JSX

JSX는 HTML 형태의 자바스크립트 객체를 사용하는 확장된 자바스크립트 문법으로, JSX를 통해 조작되는 것은 실제 DOM이 아닌 가상 DOM입니다.

React Element

Element는 type과 props를 가지는 React의 객체입니다. type으로 HTML 태그 이름을, 그 외의 특징을 props로 관리합니다. 위에서 언급한 render()가 반환한 객체가 React Element입니다.

React Component

Component는 props를 받아서 Element를 반환하는 함수 혹은 클래스를 가리킵니다. 상태값을 가지며, render()함수를 실행하는 주체입니다. Render Element Tree를 캡슐화합니다.

Component가 가상 돔에 직접 접근할 수는 없지만, Element로 쉽게 변환됩니다. Element는 빠르게 비교, 업데이트 후 가상 돔에 삽입됩니다. React가 수정 내역을 알게 되면 이 부분은 HTML DOM으로 바뀌어 실제 DOM 안으로 삽입됩니다.

요약

  • 가상돔은 브라우저의 연산을 줄여 성능을 개선합니다.
  • React Component는 render()함수를 통해 React의 객체인 Element를 반환하고, 이 객체가 가상돔을 구성합니다.
  • 가상돔을 구성하는 객체는 가독성이 좋지 않아 JSX를 사용합니다.
  • JSX를 통해 조작되는 것은 실제 DOM이 아닌 가상 DOM입니다.

--

--