Home
PostsAbout
react

React와 가상 DOM

어쩌면 뻔한 리액트와 가상 DOM 이야기

2025-01-28

DOM이란 무엇이며, 가상 DOM과 어떻게 다른가요?

DOM

  • DOM은 Document Object Model의 약자로 말 그대로 문서 객체 모델이란 뜻입니다. 보통 DOM이라고 하면 브라우저 런타임의 문서 모델을 의미합니다. 커다란 JS 객체입니다.
  • DOM은 노드 객체로 구성됩니다.

가상 DOM

  • 설명 역할을 하는(?), 정보를 가지고 있는 평범한 JS 객체입니다. DOM의 가벼운 복사본이라고 보면 됩니다.
  • 가상 DOM은 평범한 JS 객체로 구성되기 때문에 브라우저나 다른 호스트 환경에 얽매이지 않고 자바스크립트 엔진을 최대한 활용하는 다양한 알고리즘에 접근해 빠르고 효율적으로 조작할 수 있습니다.

문서 조각이란 무엇이며, 리액트의 가상 DOM과 어떤 점에서 비슷하고 다른가요?

문서 조각(Document Fragment)은 DOM 노드를 저장하는 가벼운 컨테이너입니다. 기본 DOM에 영향을 주지 않고 여러 가지 업데이트를 수행할 수 있는 임시 저장소처럼 동작합니다. 업데이트 작업이 완료되면 문서 조각을 DOM에 추가하는 방식으로 리플로우와 리페인팅을 한 번만 발생시킵니다. 업데이트 방식이 리액트의 가상 DOM과 매우 유사합니다.

비슷한 점

  • 일괄 업데이트: 문서 조각과 유사하게 리액트의 가상 DOM은 여러 변경 사항을 한꺼번에 일괄 처리합니다.
  • 효율적인 비교 알고리즘: 변경 사항이 적용되고 나면 리액트는 현재 가상 DOM과 실제 DOM의 차이점을 확인합니다.
  • 단일 렌더링: 차이점이 식별되면 리액트는 단 한 번의 일괄 처리를 통해 실제 DOM을 업데이트합니다.

다른 점

  • 라이프사이클: 문서 조각은 삽입 시 사라지며, 이후 DOM 트리에 존재하지 않습니다. 하지만 가상 DOM은 리액트의 컴포넌트 트리를 통해 지속적으로 관리되고 업데이트됩니다.
  • 더 나은 업데이트: 문서 조각은 문서의 실제 DOM을 업데이트하기 전에 변경 사항을 그룹화하여 최적화하지만, 리액트의 가상 DOM은 한 걸음 더 나아가 애플리케이션 UI 전반에 걸쳐 영리하게 차이점을 파악하고 일괄적으로 업데이트를 처리해 렌더링의 효율성을 극대화합니다. 더 나아가, 리액트는 문서 조각과 관련된 복잡한 작업을 개발자가 신경 쓰지 않아도 되도록 내부적으로 처리합니다.

DOM에서 문제가 되는 사안은 무엇인가요?

실제 DOM에는 고성능 웹 애플리케이션을 구축하기 어렵게 만드는 문제점이 몇 가지 있습니다. 성능, 브라우저 간 호환성, 보안 취약성 등이며, DOM을 직접 조작하면 크로스 사이트 스크립팅(XSS) 취약점이 생길 수 있습니다.

성능

실제 DOM에서 가장 문제시되는 사안은 성능입니다. 엘리먼트의 추가나 제거, 엘리먼트의 텍스트나 속성 업데이트 등으로 DOM을 변경할 때마다 브라우저는 레이아웃을 다시 계산하고 페이지의 영향을 받는 부분을 다시 그립니다. 특히 크고 복잡한 웹 페이지라면 이 과정은 속도가 느려지고 리소스를 많이 사용하기도 합니다.

이러한 성능 사안을 해결할 수 있는 대표적인 방법은 계산 작업을 한 번에 모아 처리하는 것입니다. 리액트는 가상 DOM을 실제 DOM 작업 간의 중간 계층으로 활용해 이러한 작업을 알아서 처리합니다.

리플로우라고 부르는 레이아웃 재계산, 리페인팅을 발생시키는 직접적인 DOM 조작은 CPU 사용량과 처리 시간을 증가시켜 사용자에게 지연이나 충돌을 일으킬 수 있습니다.

브라우저 간 호환성

브라우저마다 문서 모델링 방식이 달라 웹 애플리케이션의 일관성이 보장되지 않고, 이로 인해 버그가 발생할 수 있습니다.

브라우저 간 호환성의 주요 문제 중 하나는 특정 DOM 엘리먼트와 속성을 지원하지 않는 브라우저가 있을 수도 있다는 점입니다.

리액트의 합성 이벤트 시스템(synthetic event system)은 이러한 문제를 해결하기 위해 등장했습니다. SyntheticEvent는 브라우저의 기본 이벤트를 둘러싼 래퍼 객체로, 여러 브라우저에서 일관성을 보장하기 위해 설계되었습니다.

사용자 인터페이스를 더 빠르게 업데이트하는 데 가상 DOM이 어떻게 활용되나요?

image.png

  1. 변경 사항 비교(Diffing):

가상 DOM은 React의 내부에서 실제 DOM의 가벼운 사본으로 사용됩니다. 상태나 props의 변경으로 인해 UI 업데이트가 필요할 때 React는 새로운 가상 DOM 트리를 생성하고, 이전 가상 DOM과 비교하여 변경된 부분만 계산(diffing)합니다. 이를 통해 불필요한 작업을 최소화합니다.

  1. 배치 업데이트(Batched Updates):

React는 여러 상태 업데이트를 하나의 렌더링 주기 내에서 처리하여 실제 DOM 조작 횟수를 줄입니다. 가상 DOM은 이러한 작업을 효율적으로 처리할 수 있도록 도와줍니다.

  1. 최소한의 실제 DOM 업데이트:

비교 결과를 바탕으로, 변경된 부분만 실제 DOM에 반영합니다. 실제 DOM 조작은 비용이 큰 작업이므로, 가상 DOM을 사용하면 이를 최적화할 수 있습니다.

  1. 플랫폼 독립성:

가상 DOM은 React가 특정 브라우저 환경에 구애받지 않고 동작할 수 있도록 추상화 계층을 제공합니다. 이를 통해 React는 최적화된 방식으로 DOM 업데이트를 처리합니다.

리액트의 렌더링은 어떻게 작동하나요? 이로 인해 잠재되었던 어떤 문제가 발생할 수 있나요?

리액트의 렌더링 작동 방식

  1. 컴포넌트 기반 구조

리액트는 컴포넌트 단위로 UI를 구성합니다. 각 컴포넌트는 상태(state)나 속성(props)의 변경에 따라 렌더링됩니다.

  1. 리렌더링 트리거

컴포넌트의 상태가 업데이트되거나 부모 컴포넌트에서 새로운 props를 받으면 해당 컴포넌트와 그 자식 컴포넌트가 리렌더링됩니다.

  1. 가상 DOM을 활용
  • 리액트는 UI를 효율적으로 업데이트하기 위해 가상 DOM을 사용합니다.
  • 변경 사항이 감지되면 리액트는 가상 DOM에 새로운 트리를 생성하고 이전 트리와 비교(diffing)하여 변경된 부분만 실제 DOM에 반영합니다.
  1. 렌더링 단계
  • 렌더 단계: 컴포넌트가 가상 DOM 트리를 생성합니다.
  • 커밋 단계: 변경된 가상 DOM이 실제 DOM에 반영됩니다.

잠재적인 문제

  1. 필요한 리렌더링
  • 상태나 props가 변경될 때, 자식 컴포넌트까지 리렌더링되는 경우가 있습니다.
  • 해결 방안: React.memo를 사용하거나, useMemo, useCallback으로 값이나 함수를 메모이제이션하여 불필요한 리렌더링을 줄일 수 있습니다.
  1. 성능 저하
  • 너무 자주 렌더링이 발생하거나, 렌더링 과정에서 복잡한 계산이 포함되면 성능이 저하될 수 있습니다.
  • 해결 방안: 가상 DOM의 비교 비용을 줄이기 위해 컴포넌트 구조를 단순화하거나 React.lazy로 코드 스플리팅을 활용합니다.
  1. React의 비동기 렌더링 이슈(Suspense)
  • React 18부터 도입된 Concurrent Mode에서는 비동기적으로 렌더링이 이루어져 UI의 일관성이 깨질 수 있습니다.
  • 해결 방안: useTransition이나 Suspense를 사용하여 비동기 렌더링의 흐름을 제어합니다.
  1. 메모리 누수
  • 잘못된 이벤트 리스너 관리나, 컴포넌트 언마운트 시 정리가 되지 않으면 메모리 누수가 발생할 수 있습니다.
  • 해결 방안: useEffect에서 클린업 코드를 정확히 작성합니다.

참고 자료

  • 전문가를 위한 리액트