[React]
- [React] vite React설치
- Project initial setting
- Hooks && Library
- [React] Javascript 파일을 Typescript Import해보자
- [React] react-router-dom 알아보고 사용하자
- [React] child 컴포넌트에서 함수호출하기
- [React] useCallback
- [React] framer-motion 알아보고 사용하자
- [React] Context API
- [React] react lazy 지연로딩 예제
- [React] react에서 캐싱처리를 위한 react queryd와 indexDB 비교분석
- [React] 스타일 라이브러리 styled-components stitches 비교
- [React] 프론트 에러추적 도구 Sentry 사용해보기
- [React] React 19 주요 변경점
- [React] DOM이란 무엇이고? 가상 DOM이란 무엇인가?
- [React] preact 알아보기
🌳 DOM과 Virtual DOM의 완벽 가이드
1. DOM (Document Object Model) 이해하기
DOM이란?
DOM은 웹 페이지를 프로그래밍 언어가 이해할 수 있는 구조로 표현한 것이에요.
1
2
3
4
5
6
7
8
<!-- 실제 HTML -->
<div class="app">
<h1>안녕하세요</h1>
<ul>
<li>사과</li>
<li>바나나</li>
</ul>
</div>
이것이 트리 구조로 변환됩니다:
1
2
3
4
5
6
7
div (class="app")
/ \
h1 ul
| / \
"안녕하세요" li li
| |
"사과" "바나나"
DOM의 문제점
-
직접 조작의 비효율성
- DOM을 직접 수정할 때마다 브라우저는:
- 레이아웃 계산 다시 하기
- 리페인팅 (화면 다시 그리기)
- 리플로우 (요소 위치와 기하학적 계산)
- DOM을 직접 수정할 때마다 브라우저는:
-
성능 저하
1
2
3
4
// 비효율적인 DOM 조작의 예
for (let i = 0; i < 1000; i++) {
document.body.innerHTML += `<div>${i}</div>`; // 매번 전체 리렌더링 발생! 😱
}
2. 🚀 Virtual DOM의 등장
Virtual DOM이란?
- 실제 DOM의 가벼운 복사본
- JavaScript 객체 형태로 메모리에 존재
- 실제 DOM과 동일한 속성을 가지지만 실제로 화면을 그리는 능력은 없음
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Virtual DOM의 객체 구조 예시
{
type: 'div',
props: {
className: 'app',
children: [
{
type: 'h1',
props: {
children: '안녕하세요'
}
},
{
type: 'ul',
props: {
children: [
{
type: 'li',
props: {
children: '사과'
}
},
{
type: 'li',
props: {
children: '바나나'
}
}
]
}
}
]
}
}
3. 🔄 Diffing과 Reconciliation 프로세스
전체 과정
- 상태 변경 발생
- 새로운 Virtual DOM 생성
- Diffing 알고리즘으로 비교
- Reconciliation으로 실제 DOM 업데이트
Diffing 알고리즘의 동작
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 변경 전
<div className="before">
<h1>안녕하세요</h1>
<p>반갑습니다</p>
</div>
// 변경 후
<div className="after">
<h1>안녕하세요</h1>
<p>환영합니다</p>
</div>
// Diffing 결과
// 1. div의 className만 변경
// 2. h1은 변경 없음
// 3. p의 내용만 변경
Reconciliation 규칙
-
다른 타입의 엘리먼트
- 이전 트리를 완전히 버리고 새로운 트리 구축
-
같은 타입의 DOM 엘리먼트
- 속성만 업데이트
-
같은 타입의 컴포넌트
- 상태는 유지되고 props만 업데이트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 예시: 리스트 아이템 업데이트
// Before
<ul>
<li key="1">첫번째</li>
<li key="2">두번째</li>
</ul>
// After
<ul>
<li key="2">두번째</li>
<li key="1">첫번째</li>
</ul>
// key를 통해 순서만 변경되었다고 인식
// 전체 리렌더링 대신 위치만 변경
4. 🎯 최적화 전략
1. 적절한 key 사용
1
2
3
4
5
6
7
8
9
// ❌ 나쁜 예
{
items.map((item, index) => <Item key={index} />);
}
// ✅ 좋은 예
{
items.map((item) => <Item key={item.id} />);
}
2. 불필요한 렌더링 방지
1
2
3
4
// React.memo를 사용한 컴포넌트 최적화
const MemoizedComponent = React.memo(function MyComponent(props) {
return <div>{props.value}</div>;
});
3. 상태 관리 최적화
1
2
3
4
5
6
// ❌ 나쁜 예: 전체 객체를 상태로 관리
const [user, setUser] = useState({ name: "김철수", age: 25 });
// ✅ 좋은 예: 필요한 값만 상태로 관리
const [name, setName] = useState("김철수");
const [age, setAge] = useState(25);
5. 🎮 실제 동작 과정 시각화
-
상태 변경
1
setState({ text: "새로운 텍스트" });
-
Virtual DOM 업데이트
1 2 3 4 5 6 7
// 새로운 Virtual DOM 트리 생성 newVirtualDOM = { type: "div", props: { children: "새로운 텍스트", }, };
-
Diffing
1 2 3 4 5 6
// 변경된 부분 감지 changes = { type: "UPDATE", path: ["props", "children"], value: "새로운 텍스트", };
-
Reconciliation
1 2
// 실제 DOM 업데이트 document.querySelector("div").textContent = "새로운 텍스트";
1.루트 요소 유형에 따른 업데이트
버튼 클릭 시 상태를 변경할 때 요소와 부모가 다시 렌더링되는 방식에 주목하세요. 상태를 토글할 때 요소 유형 자체(에서
section
로 p
)를 변경하고, diffing 알고리즘에 따라 React는 이전 트리를 파쇄하고 변경된 요소의 루트/부모에서 새 트리를 만듭니다.
이제 동일한 요소 유형을 가진 비슷한 예를 살펴보겠습니다.
이 경우에는 요소 유형이 변경되지 않으므로 부모 요소가 아닌 요소만 다시 렌더링되는 것을 볼 수 있습니다(
<p>
로 유지됨 <p>
).
이렇게 전체적인 과정이 이루어지며, React는 이 모든 과정을 자동으로 최적화하여 처리합니다! 🎉
2. prop key 기반 업데이트
목록 시작 부분에 새 항목을 추가할 때 모든 형제 목록 요소가 다시 렌더링되는 것을 주목하세요. 이는
key prop을
제공하지 않았기 때문에 Diffing이 발생하면 DOM nodes목록의 모든 요소가 업데이트되는 것처럼 보이기 때문입니다.
이제 prop을 사용하여 비슷한 예를 살펴보겠습니다
key
.
여기에서는 각 항목에 고유한 ID를 부여했으므로 keyDiffing 중에 React가 각 요소를 구별할 수 있고 따라서 변경된 요소만 다시 렌더링합니다.
6.✏️ 요약
React는 이렇게 처리해요:
- Virtual DOM에서 먼저 변경을 감지해요 (Diffing)
<p>
태그의 내용만 바뀐 것을 확인하고- 해당 부분만 실제 DOM에 업데이트해요 (Reconciliation)
🎯 이렇게 하면 뭐가 좋을까요?
-
성능이 좋아져요
- 실제 DOM 조작을 최소화할 수 있어요
- 브라우저가 덜 힘들어해요
-
개발이 편해져요
- 마치 전체 페이지를 다시 그리는 것처럼 코드를 작성해도
- React가 알아서 최적화해줘요
-
사용자 경험이 좋아져요
- 화면 깜빡임이 줄어들어요
- 더 부드러운 웹 경험을 제공할 수 있어요
💪 이제 우리가 할 일은?
Virtual DOM의 장점을 최대한 활용하려면:
- 컴포넌트 구조를 잘 설계하고
- 적절한 key 값을 사용하고
- 불필요한 렌더링을 방지하면 됩니다!
이렇게 하면 React와 Virtual DOM의 진정한 힘을 느낄 수 있을 거예요! 다 .