🔹 1. DOM이란?
DOM(Document Object Model)은 브라우저가 HTML 문서를 객체로 표현한 구조입니다.
🔹 2. Virtual DOM이란?
Virtual DOM은 실제 DOM의 가벼운 자바스크립트 객체 복제본입니다.
React는 UI 변경이 필요할 때 실제 DOM을 직접 수정하지 않고, 먼저 Virtual DOM에서 그 변경을 시뮬레이션합니다.
🔹 3. Virtual DOM 작동 방식
- 초기 렌더링:
- 컴포넌트가 처음 렌더링될 때, React는 Virtual DOM을 생성하고 실제 DOM에 반영합니다.
- 업데이트 발생 (setState, props 변경 등):
- 변경이 생기면 React는 새로운 Virtual DOM을 생성합니다.
- 이전 Virtual DOM과 비교(diffing)하여 어떤 부분이 변경되었는지 찾습니다.
- DOM 패치 (Reconciliation):
- 변경된 부분만 실제 DOM에 반영합니다.
🔹 4. 왜 Virtual DOM이 빠를까?
- 전체 DOM이 아니라 변경된 부분만 갱신하기 때문입니다.
- Batch 업데이트: 여러 변경사항을 모아서 한 번에 처리합니다.
- 최적화된 diffing 알고리즘 덕분에 빠르게 비교하고 렌더링을 최소화합니다.
🔹 정리
항목 실제 DOM Virtual DOM
| 위치 | 브라우저 내부 | 메모리 상의 JS 객체 |
| 업데이트 속도 | 느림 | 빠름 |
| 사용 목적 | 화면 렌더링 | 효율적인 변경 추적 및 렌더링 최적화 |
그렇다면 실제코드 예시를 통해 리액트의 Virtual DOM이 어떻게 실제 DOM조작에 비해 성능을 최적화 하는지 알아봅시다.
✅ 1. 순수 JavaScript로 직접 DOM 조작 (비효율적 방식)
<!-- index.html -->
<button id="increment">Increment</button>
<div id="count">0</div>
// vanilla.js
let count = 0;
document.getElementById("increment").addEventListener("click", () => {
count++;
document.getElementById("count").textContent = count;
});
🧠 이 방식은 간단해 보이지만, 복잡한 DOM 구조에서는 다음 문제가 있습니다:
- DOM을 직접 조작하기 때문에 전체 DOM 트리를 다시 렌더링하는 경우가 많음
- 성능이 저하되기 쉬움 (특히 애니메이션, 리스트 등)
✅ 2. React로 구현 (Virtual DOM 사용)
// App.jsx (React)
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<div>{count}</div>
</div>
);
}
export default App;
🧠 React는 어떻게 다를까요?
- 버튼 클릭 시 setCount로 상태가 변경되면,
- 새로운 Virtual DOM이 생성됨
- 이전 Virtual DOM과 비교(diffing)
- 바뀐 부분 (<div>{count}</div>)만 실제 DOM에 반영됨
✅ 3. 성능 비교 실험 예시
리스트를 10,000개 렌더링하면서 숫자를 업데이트하는 예제를 비교해 보겠습니다.
📦 3-1. 직접 DOM 조작 (비효율 예)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vanilla JS Render Test</title>
</head>
<body>
<button id="increment">Increment</button>
<div id="root"></div>
<script>
const root = document.getElementById('root');
const render = (count) => {
//alert(count);
root.innerHTML = '';
const ul = document.createElement('ul');
for (let i = 0; i < 10000; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i} - Count: ${count}`;
ul.appendChild(li);
}
root.appendChild(ul);
};
let count = 0;
document.getElementById('increment').onclick = () => {
count++;
render(count);
};
// 초기 렌더링
render(count);
</script>
</body>
</html>
(그대로 index.html 복사후에 실행해 보면 잘 실행됩니다)
- 👎 innerHTML과 DOM 조작으로 전체 노드를 계속 재생성
- 렌더링 시간이 길어짐
- UI가 버벅거릴 수 있음
📦 3-2. React 사용 (효율적 예)
// App.jsx
import React, { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const items = Array.from({ length: 10000 }, (_, i) => (
<li key={i}>Item {i} - Count: {count}</li>
));
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ul>{items}</ul>
</div>
);
}
export default App;
- 👍 React는 변경된 count만 반영하여 diff → patch
- 전체 노드를 재생성하지 않고 DOM 최소 업데이트
- 퍼포먼스가 더 좋고 UI가 부드러움
⏱️ 성능 측정 팁
브라우저 개발자 도구(F12) > Performance 탭을 이용해서:
- React와 Vanilla JS 비교 실험 가능
- Recalculate Style, Layout, Paint 시간 비교 가능
✅ 결론
항목 Vanilla JS React (Virtual DOM)
| 전체 DOM 재생성 | 있음 | 없음 (부분 업데이트) |
| 렌더링 속도 | 느림 (특히 많은 노드) | 빠름 |
| 개발자 관리 | 직접 DOM 조작 필요 | 선언적 UI, 상태 기반 |
| 유지보수 | 어렵고 오류 가능성 큼 | 효율적, 구조적 |
출처: chatGpt
'더조은컴퓨터아카데미 리액트 주말반' 카테고리의 다른 글
| 리액트 주말반 세번째 수업 (3) | 2025.07.19 |
|---|---|
| 리액트 주말반 두번째 수업 (4) | 2025.07.13 |
| 리액트 주말반 첫번째 수업 (4) | 2025.07.12 |