본문 바로가기

개발몰입과정 개념스터디/3차

React Virtual Dom란?

[가상 돔] : 리액트, Vue js

웹 브라우저가 네트워크를 통해 HTML을 전달 받으면 브라우저의 렌더링 엔진은 HTML을 파싱하고 돔 노드(DOM Node)로 이루어진 트리를 만듭니다. 또한 CSS 파일과 HTML의 요소들(Element)의 인라인 스타일을 파싱하여 스타일 정보를 가진 스타일 트리도 생성합니다.

HTML & CSS 렌더링 과정

이렇게 렌더 트리가 완성되면 브라우저는 Attachment라는 과정을 통해 스타일 정보를 계산합니다. 렌더 트리로 생성된 모든 노드들은 attach라는 함수를 가지고 있는데, 이 Attachment라는 과정에서 이 메소드들이 호출되게 되며, 해당 메소드는 스타일 정보를 계산하고 결과값을 객체 형태로 반환하게 됩니다.

⇒ 렌더 트리로 생성된 모든 노드들은 attach라는 함수를 가지고 있는데 이를 통해 스타일정보를 계산하는 attachment라는 과정을 거친다.

 

이때 이 계산 과정은 모두 동기적(Synchronous)으로 동작하게 되며, 만약 렌더 트리에 새로운 노드가 추가된다면 해당 노드의 attach 메소드가 실행되어 계산 과정을 거치게 됩니다.

 

렌더 트리는 Attachment 과정을 거친 후 레이아웃이라는 과정을 거치게 됩니다. 이 레이아웃 과정에서는 브라우저가 렌더 트리의 각 노드들에 좌표를 부여하고 정확히 어디에 어떻게 표시되는지를 결정합니다.

⇒ attachment → 레이아웃 : 각 노드들에 좌표 부여 (어디에 표시되는지 결정)

 

마지막으로 브라우저는 페인팅(Painting)이라는 과정을 거치게 됩니다. 이 페인팅 과정에서는 각 노드들에 paint 함수를 호출하여 렌더링된 요소들에 색상을 입히게 됩니다.

⇒ 레이아웃 → 페인팅 : 각 노드들의 paint함수를 호출해 렌더링 요소에 색상을 입힘

 

이런 과정을 거쳐 표시된 HTML을 자바스크립트를 사용하여 DOM을 조작하게 되면 각 노드의 좌표를 계산하기 위해 레이아웃 과정이 다시 실행되고, 그 이후 색상을 입히기 위한 페인팅 과정이 다시 진행되게 됩니다. 이렇게 DOM 조작으로 레이아웃 과정이 다시 진행되는 것을 리플로우(Reflow)라고 하며, 페인팅 과정이 다시 진행되는 것을 리페인트(Repaint)라고 합니다. 이 리플로우와 리페인트는 DOM의 각 노드에 대한 연산 과정을 다시 수행함으로 이 과정이 많이 수행될수록 웹 서비스의 성능이 저하되는 문제가 발생하게 됩니다.

⇒ 따라서 DOM을 조작하면 다시 각 노드의 자표를 계산하기 위해 레이아웃(리플로우)과 다시 색을 입히는 페인팅(리페인트)과정이 다시 실행된다. 리플로우와 리페인트는 웹 성능을 저하시킨다.

 

리액트는 이 리플로우와 리페인트가 자주 수행되는 문제를 해결하기 위해 화면에 표시되는 DOM과 동일한 DOM을 메모리상에 만들고 DOM 조작이 발생하면 메모리상에 생성한 가상 돔에 모든 연산을 수행한 후, 실제 DOM을 갱신하여 리플로우/리페인트의 연산을 최소화하였습니다.

⇒ 이 문제를 해결하기 위해, 화면에 표시되는 DOM과 동일한 가상 DOM을 메모리상에 만들고 조작이 발생하면 가상 돔에 연산을 수행한 후, 실제 DOM에 갱신시킨다.

 

예를 들어 사용자가 Todo 리스트 앱을 사용할 때, 아무것도 없던 리스트에 할일을 하나 추가하는 과정을 생각해 봅시다. 할일을 입력하고 추가 버튼을 누르면, 아무것도 없던 리스트에 할일을 하나 표시하고, 전체 할일 개수를 표시합니다. 이 때, 가상 돔이 없는 경우, 할일을 하나 표시하기 위해 리플로우/리페인트가 한 번 발생하고, 전체 할일 개수를 표시하기 위해 리플로우/리페인트가 다시 한 번 발생하게 됩니다.

하지만, 리액트에서는 이 모든 과정을 가상 돔에서 수행합니다. 따라서 사용자가 할일을 입력하고 추가 버튼을 누르면, 할일 표시, 전체 할일 개수를 표시하기 위해 가상 돔에서 계산을 한 후, 계산 결과를 브라우저에 전달하여 리플로우/리페인트를 한 번만 수행하도록 합니다.

'개발몰입과정 개념스터디 > 3차' 카테고리의 다른 글

React Hooks란?  (0) 2022.02.05
Class Component vs Functional Component  (0) 2022.02.05
JWT란?  (0) 2022.02.05
CORS란?  (0) 2022.02.05
JavaScript의 비동기 기술  (0) 2022.02.05