[React] Virtual DOM

Haz·2024년 6월 27일
1

개발여행기

목록 보기
26/32

<팀 스파르타 인턴즈 1기> 웹 개발 파트에 지원해서 면접을 보는데 세상에 Virtual Dom에 관련된 질문을 하시는데 순간 머리가 하얘져서 메모리를 아낄 수 있다는 말도 안되는 답변을 하고 말았다. 심지어 면접관님이 다시 기회를 주셨는데도 제대로 회복할 수가 없었고 제대로 망했다는 생각이 머리를 스쳤다.

OMG(뉴진스 노래 아님)

타입스크립트도 제대로 모르면서 리액트 작동 원리도 제대로 머릿속에 못 넣어두고 뭔 취업을 하겠다고..!!! 기술 면접 이래서 보겠나 싶어 머리에 우겨넣기 위해 오늘은 Virtual DOM을 부셔보자.



Virtual DOM


virtual dom

DOM이 뭔지는 다들 알고 있을 것이다. HTML을 활용해 웹페이지에 컴포넌트를 그리기 시작할 때 DOM 트리가 생기고 Element 요소들이 순차적으로 화면에 그려지기 시작한다.

결국 DOM은 화면에 그려진 태그 상 요소들인 셈인데 그렇다면 도대체 Virtual DOM은 뭘까?

Virtual DOM이란?

Virtual: 가상의

사전적인 의미로만 보자면 Virtual DOM(VDOM)이라는 건 현실에 존재하지 않는 가상의 DOM이라는 뜻이다. 복사본을 만들어서 실제 DOM이 아니라 객체 형태로 메모리 안에 저장한다.

재조정: UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념

React 공식문서(더는 업데이트되진 않지만 이전 버전 문서에만 설명이 있으니 참고만 하자)에 따르면 Virtual DOM은 위와 같은 의미다.

이 방법으로 React 선언적 API가 가능해지며 Attribute 조작, 이벤트 처리, 수동 DOM 업데이트를 추상화할 수 있다.

공식문서에서는 이 VDOM을 기술이 아니라 패턴에 가깝다고 말한다. 그렇기에 Shadow DOM(웹 컴포넌트의 범위 지정 변수 및 CSS용으로 설계된 브라우저 기술)과는 달리 브라우저 "API" 위에서 JavaScript 라이브러리로 구현되는 개념이다.

작동 원리

인터뷰에서 가장 문제가 됐던 부분이다😂 메모리를 아낄 수 있다고 했던 바로 그 부분.

사실 Virtual DOM을 사용하면 어쩔 수 없이 추가적으로 메모리를 사용해야한다. 사용할지, 아닐지도 모르는 VDOM을 객체 형태로 저장하고 있어야하기 때문이다.

다만, VDOM을 사용하게 되면 UI가 변경되서 새로 렌더링을 할 때 모든 DOM 트리를 새로 그리지 않아도 된다는 장점이 있다. 애플리케이션에서 DOM 조작이 얼마나 잦은지를 파악해 VDOM을 사용하는 것이 이익이라면 VDOM이 오히려 성능 향상 방법이 된다.

현재 대부분의 웹, 애플리케이션에서 페이지의 일부 UI만 새로 그리거나 데이터를 주기적으로 업데이트해서 보여주는 경우가 획기적으로 늘어났다. 그래서 React 같은 CSR 프레임워크들이 각광 받게 됐고, Virtual DOM을 활용해 DOM을 조작하는 것이 더 효율적이라고 인정받게 된 것이다.

리액트에서 DOM 트리 비교

작동 과정

실제로는 어떤 과정으로 Virtual DOM이 작동할까? 위에서 설명했던 재조정 과정을 통해서 실제 DOM과 VDOM이 동기화되는데 아래와 같은 단계를 거친다.

  1. UI가 변경을 감지
  2. UI를 VDOM으로 가상 렌더링
  3. 변경할 DOM과 기존 DOM을 비교해(Diffing) 차이를 계산
  4. 변경된 부분만을 실제 DOM에 반영

Diffing 이라는 효율적인 알고리즘으로 신속하게 기존 UI DOM을 가상화한 버전과 변경할 버전을 비교해서 차이점을 파악하고 적용한다. 일일이 변경된 DOM을 교체해야해서 작업이 무거울 것 같지만, Batch Update 덕분에 그렇지 않다.

이는 변경된 모든 요소들을 집단화해 한꺼번에 실제 DOM에 적용하는 방식으로 10개의 DOM이 변경됐다면 이를 10번 반복해 수정하는 게 아니라 한 번에 집단화해서 적용하는 식이다.

얕은 비교

React에서는 DOM 트리의 노드를 비교할 때 얕은 비교를 한다. 그렇기 때문에 배열, 객체 같은 자료형은 메서드로 배열을 수정해 setState에 담아도 같은 참조 위치를 가지고 있기 때문에 실제 값의 변화를 반영하지 않는다는 점을 조심해야한다.



React Fiber


React는 컴포넌트 트리에 대한 추가 정보를 포함하기 위해 "fibers"라는 내부 객체를 사용하는데 이것이 React에서 VDOM을 구현한 부분의 일부로 간주된다.

정의와 목적

기존에 VDOM을 다루던 방식은 기존 Stack 기반 업데이트 방식은 작업을 순차적으로 처리하기 때문에, 긴 작업 시간으로 인해 UI가 멈추거나 사용자 입력에 대한 반응이 느리다는 문제가 있었다.

Virtual DOM을 좀 더 발전된 방식으로 사용하기 위한 React의 새로운 재조정(Reconciliation) 엔진으로, 다음과 같은 목적으로 개발됐다.

  • 사용자 경험 개선: Fiber는 작업을 점진적으로 처리하고 중단할 수 있는 기능을 제공하여, 프레임 드롭을 방지하고 부드러운 사용자 경험을 제공
  • 성능 향상: Fiber는 작업의 우선순위를 고려하여 스케줄링하고, 재사용 가능한 작업 단위를 활용함으로써 메모리 사용을 최적화하여 전반적인 성능을 향상
  • 재조정 알고리즘 개선: Fiber는 기존 React의 재조정 알고리즘을 개선하여, UI 트리의 변경 사항을 더 효율적으로 감지하고 업데이트
  • 대규모 애플리케이션 지원: Fiber의 개선된 재조정 기능으로 인해, 대규모 애플리케이션에서도 원활한 동작이 가능

특징

이와 같은 목적을 달성하기 위해 Fiber는 다음과 같은 주요 특징을 가지고 있다.

  • 증분 렌더링: 작업 단위를 나누어 점진적으로 처리
  • 우선순위 기반 스케줄링: 작업의 우선순위를 고려하여 스케줄링
  • 중단 가능한 작업: 작업을 언제든지 중단 가능
  • 재사용 가능한 작업 단위: 작업 단위를 재사용

이렇게 재조정 알고리즘을 개선하여 UI 트리의 변경 사항을 효율적으로 감지하고 업데이트가 가능해졌고, 사용자 입력에 대한 반응성을 높이며, 작업 단위를 세분화하고 점진적으로 처리할 수 있어, 긴 작업 시간으로 인한 UI 프리징 문제를 해결할 수 있게 되었다.

구조

  • Fiber 노드: Fiber의 작업 단위로, 렌더링해야 할 엘리먼트에 대한 정보(컴포넌트 유형, props, 상태 등)와 작업 상태 정보를 가짐
  • 링크드 리스트 구조: Fiber 노드는 서로 연결된 링크드 리스트 구조를 이룸
  • 부모-자식 관계: Fiber 노드는 부모-자식 관계를 가지고 있어, UI 트리의 구조를 표현
profile
나도 재밌고, 남들도 재밌는 서비스 만들어보고 싶다😎

0개의 댓글