[React] VDOM의 원리
리액트의 **Virtual DOM (VDOM)**은 리액트가 성능을 최적화하여 효율적으로 UI를 업데이트하기 위해 사용하는 중요한 개념입니다. VDOM의 동작 원리는 브라우저의 실제 DOM을 직접 조작하는 대신, 메모리 상에서 가상 DOM을 만들어 변경 사항을 미리 계산하고, 최소한의 업데이트만 실제 DOM에 반영하는 방식으로 이루어집니다.
VDOM의 동작 원리
VDOM은 UI 업데이트 과정을 세 가지 주요 단계로 나눌 수 있습니다:
1. 상태 변화로 인해 VDOM이 갱신됨
2. 리액트의 Diffing 알고리즘이 이전 VDOM과 새 VDOM을 비교
3. 최소한의 변경 사항만 실제 DOM에 반영 (Reconciliation)
각 단계의 동작을 하나씩 자세히 살펴보겠습니다.
1. 상태 변화로 인해 VDOM이 갱신됨
리액트 컴포넌트는 상태(state)와 props가 변경될 때마다 자동으로 다시 렌더링됩니다. 하지만 이때 실제 DOM을 바로 업데이트하지 않고, Virtual DOM이 먼저 갱신됩니다.
과정:
• 리액트에서 상태나 props가 변경되면 컴포넌트가 다시 렌더링됩니다.
• 이때 리액트는 컴포넌트 내에서 JSX로 작성된 UI를 사용하여 새로운 Virtual DOM 트리를 생성합니다.
• 이 Virtual DOM은 실제 DOM과 동일한 구조를 가지고 있지만, 메모리 상에 존재하는 가상의 객체입니다.
예시:
function App() {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
• 위 코드에서 버튼을 클릭하여 setCount로 상태를 업데이트하면, 리액트는 새로운 VDOM을 생성합니다. 이때 h1 태그의 값이 count + 1로 업데이트된 VDOM을 메모리에 유지합니다.
2. 리액트의 Diffing 알고리즘 (VDOM 비교)
리액트의 diffing 알고리즘은 이전 VDOM과 새로운 VDOM을 비교하여, 변경된 부분만 찾는 과정을 말합니다. VDOM을 비교하는 이유는 성능을 최적화하기 위해서입니다. 전체 DOM을 다시 렌더링하지 않고, 오직 변경된 부분만 찾아내서 효율적으로 업데이트하기 위함입니다.
diffing 과정:
• 리액트는 이전에 렌더링된 VDOM과 새로운 VDOM을 비교합니다.
• 두 트리 구조의 차이를 비교하여, 변경된 노드만 추적합니다.
• 리액트는 이 차이를 바탕으로 실제 DOM을 최소한으로 업데이트할 준비를 합니다.
diffing의 특징:
1. 동일한 레벨에서만 비교: VDOM의 트리 구조에서 같은 레벨에 있는 노드들만 비교합니다. 상위 노드가 변경되면, 하위 노드도 함께 다시 렌더링됩니다.
2. Key를 사용한 최적화: 리액트는 리스트가 있는 경우 key 속성을 사용하여 각 노드를 고유하게 식별합니다. key가 없다면, 리스트가 변경될 때 전체를 다시 렌더링해야 하므로 비효율적입니다.
diffing 알고리즘 예시:
• 이전 VDOM:
<div>
<h1>0</h1>
<button>Increment</button>
</div>
• 새로운 VDOM (상태 업데이트 후):
<div>
<h1>1</h1>
<button>Increment</button>
</div>
• 리액트의 diffing 알고리즘은 <h1> 태그의 내용이 변경되었음을 감지하고, 이 부분만 실제 DOM에 업데이트하게 됩니다.
3. 최소한의 변경 사항만 실제 DOM에 반영 (Reconciliation)
리액트는 diffing 알고리즘으로 변경된 부분을 찾으면, 그 변경 사항을 실제 DOM에 반영하는데, 이 과정을 **Reconciliation (조정)**이라고 합니다.
Reconciliation 과정:
• diffing에서 찾아낸 변경 사항을 기반으로 실제 DOM을 업데이트합니다.
• 변경된 부분만 실제 DOM에 반영하기 때문에, 전체 페이지를 다시 렌더링하지 않아도 됩니다. 이를 통해 리액트는 성능을 최적화합니다.
• 리액트는 브라우저의 DOM API를 사용해 필요한 부분을 수정하고, 브라우저는 이를 반영해 리페인트(repaint) 과정을 수행합니다.
예시:
• 리액트는 diffing 결과를 바탕으로 h1 태그의 내용만 변경하고, 나머지 DOM은 그대로 유지됩니다.
<div>
<h1>1</h1> <!-- 이 부분만 변경됨 -->
<button>Increment</button>
</div>
VDOM의 장점
1. 성능 최적화
• 리액트는 VDOM을 통해 변경된 부분만 효율적으로 찾아내고, 필요한 최소한의 DOM 조작만 수행합니다. 이로 인해 브라우저의 리렌더링 부담이 줄어들고, 성능이 개선됩니다.
2. 선언형 코드 스타일
• VDOM 덕분에 리액트에서 선언형 방식으로 코드를 작성할 수 있습니다. 개발자는 DOM 업데이트 방식을 직접 관리하지 않고, 상태와 UI의 관계만 신경 쓰면 됩니다. 리액트가 VDOM을 통해 상태 변화에 따른 최적의 DOM 업데이트를 자동으로 처리합니다.
3. 브라우저와 독립적인 동작
• VDOM은 메모리 상에서 동작하므로, 브라우저와 독립적으로 수행됩니다. 이는 SSR(서버 사이드 렌더링)과 같은 환경에서 효율적으로 사용할 수 있는 장점이 있습니다.
요약: VDOM 동작 원리의 흐름
1. 상태 변경: 리액트 컴포넌트의 상태가 변경되면 새로운 VDOM이 생성됩니다.
2. VDOM 비교: 리액트의 diffing 알고리즘이 이전 VDOM과 새 VDOM을 비교하여 변경된 부분을 찾아냅니다.
3. DOM 업데이트: diffing 결과를 바탕으로 실제 DOM에 최소한의 업데이트만 반영합니다. 이를 Reconciliation이라고 합니다.
VDOM 동작의 전체적인 흐름
1. 컴포넌트의 **상태(state)**나 props가 변경됨 → 새 VDOM 생성
2. 리액트가 이전 VDOM과 새로운 VDOM 비교 → 변경된 부분만 찾음 (diffing)
3. 실제 DOM에 최소한의 업데이트만 적용 (Reconciliation) → 브라우저는 변경 사항을 반영하여 리페인트
리액트의 Virtual DOM은 이러한 과정을 통해 성능을 극대화하고, 개발자가 상태 중심으로 UI를 쉽게 관리할 수 있게 해줍니다.