2025. 8. 25. 22:27ㆍ프로젝트
0. 목차
- 서론
- DOM(Document Object Model)이란?
- Virtual DOM이란?
- 렌더링과 페인팅의 차이
- Virtual DOM의 Diffing 알고리즘
- 실제 DOM의 수정은 어떻게 일어나는가?
- 결론
1. 서론
프론트엔드 개발을 공부하면서 처음에는 “어차피 부모가 리렌더링되면 자식도 다 같이 리렌더링 되는 거 아닌가? 그렇다면 Virtual DOM을 쓸 이유가 뭐지?”라는 의문이 있었습니다.
지금 생각해보면 그건 제가 React의 “렌더링(rendering)”과 브라우저의 “페인팅(painting)”을 명확히 구분하지 못했기 때문이었습니다.
이번 글에서는 그 과정을 정리하면서, DOM과 Virtual DOM, 그리고 실제 DOM이 어떻게 수정되는지에 대해 이해한 내용을 공유해 보겠습니다.
2. DOM(Document Object Model)이란?
DOM은 HTML 문서를 브라우저가 해석해서 메모리 속 객체 트리로 표현한 구조입니다.
즉, 우리가 작성한 HTML 파일 그 자체가 아니라, 브라우저 엔진이 만든 실시간 조작 가능한 데이터 구조입니다.
- 노드(Node): 태그, 속성, 텍스트 모두 노드로 표현
- 객체화: JavaScript에서는 document 객체를 통해 접근 가능
- 위치: 하드디스크가 아니라 브라우저 엔진 메모리 속에 존재
<html>
<body>
<h1>Hello</h1>
<p>World</p>
</body>
</html>
위 HTML은 다음과 같이 트리 형태의 DOM으로 변환됩니다:
Document
└─ html
└─ body
├─ h1 → "Hello"
└─ p → "World"
3. Virtual DOM이란?
Virtual DOM은 브라우저의 DOM 트리를 메모리 속 JavaScript 객체로 가볍게 복제한 것입니다.
React 같은 라이브러리에서 사용하는 개념으로, DOM 조작의 비용을 줄이기 위해 도입되었습니다.
동작 과정
- 상태/props 변경 → 새로운 Virtual DOM 생성
- 이전 Virtual DOM과 비교(diffing)
- 달라진 부분만 찾아내기
- 그 변경 사항만 실제 DOM에 반영(commit)
이 방식 덕분에 전체 DOM을 무겁게 다시 그리는 대신, 바뀐 부분만 최소한으로 고칩니다.
4. 렌더링과 페인팅의 차이
제가 처음 오해했던 지점은 바로 여기였습니다.
저는 한동안 “컴포넌트가 리렌더링된다 = 브라우저가 화면을 다시 그린다” 라고 생각했는데, 사실은 전혀 다른 단계였습니다.
- React에서의 Rendering
→ 컴포넌트 함수가 다시 실행되고, 그 결과로 JSX를 반환
→ 이건 JavaScript 연산일 뿐, 브라우저 화면에는 아직 아무 일도 일어나지 않음 - 브라우저의 Painting
→ Virtual DOM diff 결과로 실제 DOM이 변경되면, 브라우저 엔진이 이를 받아
→ 레이아웃 계산(Layout) → 페인트(Paint) → 합성(Composite) 단계를 거쳐 화면 픽셀에 반영
| 구분 | Rendering (React) | Painting (Browser) |
| 실행 위치 | JS 엔진 | 브라우저 렌더링 엔진 |
| 하는 일 | 컴포넌트 함수 실행 → JSX 반환 | 실제 DOM 변경 후 픽셀 다시 그림 |
| 비용 | 가볍다 | 무겁다 |
| 발생 조건 | state/props 변경 | Virtual DOM diff 결과로 실제 DOM 수정 발생 |
즉, 컴포넌트 함수가 다시 실행(rendering)되었다고 해서 브라우저가 반드시 다시 그린다(painting)는 뜻은 아니다 라는 점이 핵심입니다.
5. Virtual DOM의 Diffing 알고리즘
Virtual DOM의 핵심은 “변경 사항을 최소 단위로 찾아내는 것”입니다.
React는 성능을 위해 다음과 같은 단순화된 규칙을 둡니다:
1. 타입이 같은 요소는 속성만 비교 후 업데이트→ div 유지, className만 수정
<div className="red" /> → <div className="blue" />
2. 타입이 다른 요소는 새로 생성→ div 삭제, span 생성
<div /> → <span />
3. 리스트(children)는 key로 비교→ key 값이 같으면 같은 요소로 간주, 위치만 바꿈
<li key="a" /> <li key="b" /> → <li key="b" /> <li key="a" />
4. 이렇게 diff 결과가 나오면 React는 그에 맞춰 DOM API를 호출합니다.
6. 실제 DOM 수정은 어떻게 일어나는가?
DOM을 직접 관리하는 건 브라우저 엔진이지만, JavaScript는 DOM API를 통해 간접적으로 조작할 수 있습니다.
예시:
const el = document.createElement("div"); // 새로운 div 생성
el.textContent = "Hello"; // 텍스트 삽입
document.body.appendChild(el); // body에 붙이기
React도 결국 이와 같은 API를 사용합니다:
- createElement, appendChild, removeChild
- setAttribute, textContent
즉, React는 Virtual DOM diff 결과를 바탕으로 “어떤 DOM API를 호출할지” 결정하고, 브라우저 엔진에게 “이 부분만 고쳐줘”라고 요청하는 셈입니다.
7. 결론
- DOM: 브라우저 엔진 메모리 속의 문서 객체 트리
- Virtual DOM: DOM을 JS 객체로 가볍게 복제 → diff 계산 후 최소 변경만 반영
- React Rendering: 컴포넌트 함수 호출, Virtual DOM 생성 (JS 연산)
- Browser Painting: 실제 DOM 변경 반영, 픽셀 다시 그림 (브라우저 엔진 작업)
결론적으로, 제가 처음에 가졌던 의문, “부모가 리렌더링되면 자식도 전부 리렌더링 되는데 Virtual DOM은 왜 쓰는 거야?”
그 답은, 렌더링과 페인팅은 다르기 때문이었습니다.
'프로젝트' 카테고리의 다른 글
| React Hook의 등장 배경 (3) | 2025.08.22 |
|---|---|
| NPM(Node Pacakge Manager) (5) | 2025.08.15 |
| SPA(Single Page Application) , Client-Side Routing (1) | 2024.06.12 |
| JWT(Json Web Token) 이해하기 (0) | 2024.05.16 |
| [GradeCalculator] TextField 컴포넌트의 error 속성 활용하기 (React js, Material UI) (0) | 2023.11.21 |