https://gyumingomin.tistory.com/49
Mini - Virtual DOM 프로젝트 (중점 : Virtual DOM의 이해 확장)
https://github.com/IMGyuGo/project-virtual-DOM GitHub - IMGyuGo/project-virtual-DOM: Virtual DOM 스터디 프로젝트 : 4주차 팀원 [김규민, 김민철, 김진호, 강Virtual DOM 스터디 프로젝트 : 4주차 팀원 [김규민, 김민철, 김진
gyumingomin.tistory.com
참고 : 우선 위 사이트부터 보고 오는 것을 추천 드립니다.
위 사이트에서는 "DOM의 엔진 흐름이 무엇"이고 "왜 Virtual DOM이 생겨났는가?"를 알아봤다.
그럼 막상 생각해 보았을 때, 과연 이것말고 더 확장할 수 있는 생각의 흐름을 그대로 표현해보고자 한다.
1. 과연 Virtual DOM이 마냥 좋은 것일까?
2. Diff 알고리즘은 무엇일까?
3. 브라우저는 과연 느린가? 언제 사용해야 하는가?
4. Virtual DOM 말고 다른 건 없을까? (Signals, Svelte 등)
5. SSG(Static Side Generation)의 등장! 무엇이 다를까?
6. 왜 React는 Virtual DOM을 선택했을까?
7. Virtual DOM vs 실제 DOM 흐름 비교
8. Virtual DOM과 CSR / SSR / SSG의 관계
1. 과연 Virtual DOM이 마냥 좋은 것일까?
나도 그렇고 많은 분들이
Virtual DOM = 무조건 빠르다
Virtual DOM을 처음 공부할 때는 무조건 빠를 가능성이 높다고 생각하게 된다.
하지만 좀 더 사고의 확장을 가해본다면,
Virtual DOM의 본질은 성능 최적화 기술이라기 보단 복잡한 UI 생태를 쉽게 관리하기 위한 설계 방식에 가깝다.
- 기존 방식 -
이벤트 발생 → 직접 DOM 수정
- In React -
상태 변경 -> UI 자동 갱신
즉, "어떻게 빠르게 만들까?" 보다 "어떻게 유지보수 가능한 구조로 만들까?"가 더 큰 목적이었다. (추상화)
그래서 흐름을 이해해보자면
상태 변경
-> 새로운 Virtual DOM 생성
-> 이전 Virtual DOM과 비교(diff)
-> 바뀐 부분만 실제 DOM에 patch
이런 흐름을 따라 메모리 안에 가벼운 JS 객체 형태의 UI 트리를 하나 더 두고, 실제 DOM에 반영하는 방식이다.
그래서 여기서 중요한 점을 생각할 수 있다. DOM의 reflow, repaint 과정을 많이 줄여줘서 엄청 빠른게 아닌가?
그렇지만, Virtual DOM을 생성하는 비용도 있고, 비교(diff) 하는 비용도 있고, 결국 마지막에는 DOM에 수정도 해야한다.
(공짜 최적화가 NONO!)
그래서 마냥 좋다고만은 할 수 없는 것이다.
(큰 리스트나 고빈도 업데이트에서는 비효율적일 수 있다.)
- 초당 수십~수백 번 업데이트되는 UI
- 대규모 테이블
- 실시간 그래프
- 게임 화면
- 아주 긴 리스트
(주식 차트 / 실시간 대시보드)
가격이 매우 자주 바뀌는 UI에서는 매번 Virtual DOM 트리를 만들고 비교하는 과정이 부담될 수 있다.
Canvas, WebGL, 직접 DOM 제어, 더 세밀한 반응형 시스템(Signals 등)이 더 잘 맞을 수 있다.
(10000개 리스트 렌더링)
리스트 전체를 렌더 함수로 다시 계산하면, 실제 DOM patch가 적더라도 비교 대상 자체가 너무 많아질 수 있다.
그래서 이런 경우 보통
- Visualization
- Windowing
- memorization
- fine-grained reactivity
같은 추가 최적화가 필요하다.
즉 Virtual DOM만으로는 해결되지 않는다.
2. Diff 알고리즘은 무엇일까?
Virtual DOM의 핵심은 Diff 알고리즘이다.
두 개의 Virtual DOM을 비교해서 실제 DOM에서 바뀐 부분만 업데이트한다.
문제 : Tree Diff는 원래 O(n³)이다.
모든 하위 노드를 자유롭게 재배치할 수 있고
어떤 노드가 어떤 노드와 대응되는지 모르는 상태에서
삽입, 삭제, 이동, 교체를 모두 고려해
최적 편집 비용을 찾으려 하면 복잡도가 매우 커짐
그래서 React는 이 문제를 정면으로 풀지 않고,
1) 타입이 다르면 다른 트리로 본다
<div>...</div>
<span>...</span>
으로 바뀌면
React는 이걸 "같은 노드의 수정"으로 깊게 분석하지 않고 그냥 '기존 서브트리를 버리고 새로 만든다'고 본다.
(이렇게 하면 비교 비용이 크게 줄어듬)
2) key로 자식의 정체성을 알려준다.
예를 들어 리스트가 있을 때
[ A, B, C ]
[ B, C, A ]
로 바뀌었다고 가정하자
key가 없으면 React는 기본적으로 같은 위치끼리 비교하려는 성향이 강해
첫번째 A <-> B
두번째 B <-> C
세번째 C <-> A
이런식으로 비교하게 되어
전부 다 바뀌었다고 판단
따라서
<li key="A">A</li>
<li key="B">B</li>
<li key="C">C</li>
처럼 각 자식의 identity를 알 수 있어서 React는 훨씬 쉽게 판단 가능하다.
그래서 정리하자면, Tree Diff가 왜 O(n³)인지는 정확히 몰라도
타입이 다르면 다른 트리로 본다는 전제 1
Key로 자식의 정체성을 알려준다는 전제 2
이 두가지 전제가 O(n³) -> O(n)으로 바뀌게 해준다.
React의 현실적인 타협
1. 같은 레벨끼리만 비교
2. 타입이 다르면 전체 교체
3. key로 요소 추적
3. 브라우저는 과연 느린가? 언제 사용해야 하는가?
과거에는 DOM 조작이 느렸다.
하지만 지금은
- Blink
- Webkit
같은 엔진들이 이미 최적화 되어 있다. 따라서 Virtual DOM을 사용해도 별 차이를 느끼진 못할것이다.
오히려 변화가 적은 화면상에서는 없는 게 더 나을 수도 있다.
- Virtual DOM이 필요한 경우
| Virtual DOM 필요 | Virtual DOM 필요 X |
| - 상태 변화가 많음 - UI가 복잡함 - 컴포넌트 구조 필요 - 복잡한 상태 관리 - 대규모 앱 - 유지보수 중요 |
- 정적 페이지 - 단순 UI - 퍼포먼스 극한 요구 (초고성능 요구) |
4. Virtual DOM 말고 다른 건 없을까? (Signals, Svelte 등)
최근 프레임워크들은 Virtual DOM 형태를 벗어나고 있다고 한다. (유행과 점유률은 아직 React)
ⓐ. SolidJS
- Virtual DOM 없음
- 변경된 부분만 직접 업데이트
- Diff 없음 -> 빠름
ⓑ. Svelte
- 컴파일 단계에서 최적화
- Virtual DOM 자체 제거
ⓒ. Signals 기반
- 상태변경 -> 즉시반응
핵심 흐름
Diff 기반 -> 직접 반응 기반으로 진화 중
5. SSG(Static Side Generation)의 등장! 무엇이 다를까?
- 빌드 시점에 HTML을 미리 생성해서 저장해두고, 요청 시 그대로 반환하는 방식

기존 SPA[CSR] (React)의 문제는 명확하다.
- 초기 로딩이 느림 (JS 다운로드 + 실행 필요 - 메모리가)
- SEO 취약 (검색엔진에 잘 노출되지 않음)
- 클라이언트에서 너무 많은 일을 처리 (js 객체의 update 내역을 살펴보는 것)
그래서 나온 것이 SSR Hydration (React)
하지만 이것도 한계가 있었다.
- 요청마다 서버에서 HTML 생성 -> 서버 부하
- TTFB(Time To First Byte) 증가 가능
- 인프라 비용 증가
이래서 나오게 된 것이 SSG이다.
- 서버는 계산을 하지 않는다.
- 그냥 정적 파일을 CDN(Content Delivery Network)에서 바로 내려준다.
SSG의 장점
ⓐ. 압도적인 속도 (이미 완성된 HTML)
ⓑ. SEO 완벽 대응
ⓒ. 서버 비용 거의 없음 (CDN 캐싱)
ⓓ. 트래픽 증가에도 안정적
그런데 SSG는 왜 "등장"했을까?
여기서 Svelte와 연결되는 포인트가 나온다.
정적 웹 (HTML)
→ 동적 웹 필요 증가
→ SPA (CSR + Virtual DOM)
→ 성능/SEO 문제
→ SSR
→ 서버 부담 문제
→ SSG
→ "애초에 JS를 줄이면 되지 않을까?"
→ Svelte 등장
SSG vs Svelte
공통 문제
둘 다 같은 문제에서 출발한다.
"브라우저에서 너무 많은 일을 하고 있다."
- Virtual DOM diff 비용
- hydration 비용
- JS 번들 크기 증가
SSG의 접근
"계산을 미리 해버리자 (build time)"
- HTML을 미리 만들어둠
- 런타임 부담 감소
Svelte의 접근
"애초에 런타임 계산을 없애자"
- Virtual DOM 없음
- diff 알고리즘 없음
- 컴파일 시점에 DOM 업데이트 코드 생성
React:
상태 변경 → Virtual DOM → Diff → 실제 DOM
Svelte:
상태 변경 → 바로 DOM 업데이트 코드 실행
6. 왜 React는 Virtual DOM을 선택했을까?
- 당시 상황
- jQuery -> 직접 DOM 조작
- 코드 복잡도 多
- React의 철학
- DOM을 직접 건드리지 말자
- 상태 기반 UI를 만들자
그래서 등장했다.
Virtual DOM은 성능이 아니라 “개발 모델 개선”을 위해 만들어졌다
7. Virtual DOM vs 실제 DOM 흐름 비교
<기존 방식>
이벤트 → DOM 직접 수정
<React 방식>
State 변경
→ Virtual DOM 생성
→ Diff
→ 실제 DOM 업데이트
8. Virtual DOM과 CSR / SSR / SSG의 관계
<CSR>
브라우저에서 JS 실행 → Virtual DOM 생성 → 실제 DOM 생성
<SSR Hydration>
서버에서 HTML 생성 → 브라우저 전달 → Hydration → Virtual DOM 연결
<SSG>
빌드 시점에 HTML 생성 → CDN에서 그대로 반환
└─ <SSR Hydration> Hydration과 Virtual DOM 연결
SSR → HTML 생성
↓
브라우저 표시
↓
Hydration
↓
Virtual DOM 연결
↓
이후 Diff 수행'정글캠프-WIL > 프로젝트' 카테고리의 다른 글
| Sql 처리기 - Sql Processor 프로젝트 (구현 설명 중점) (0) | 2026.04.09 |
|---|---|
| Mini-React 프로젝트 회고 (0) | 2026.04.03 |
| Mini - Virtual DOM 프로젝트 (중점 : Virtual DOM의 이해 확장) (0) | 2026.03.26 |
| 웹에 대해서... (SSR -> CSR -> SSR Hydration -> SSG) (0) | 2026.03.26 |
| Mini-Redis 프로젝트 (중점 : Redis에 관해서) (0) | 2026.03.19 |