Among Us - Black Crewmate
본문 바로가기
공부/JavaScript

JavaScript 언어의 가상 DOM(Virtual DOM) 이해하기

by k.engineer 2024. 5. 20.

 

웹 개발의 복잡성이 증가하면서 효율적인 UI 업데이트가 중요해졌습니다. 이 글에서는 자바스크립트 언어에서 중요한 개

념 중 하나인 가상 DOM(Virtual DOM)에 대해 설명하고, 이를 통해 어떻게 웹 애플리케이션의 성능을 향상시킬 수 있는지 알아보겠습니다.

 


 

1. DOM(Document Object Model)란?
DOM은 HTML, XML 문서의 구조를 트리 구조로 표현한 것으로, 자바스크립트를 통해 문서의 내용, 구조, 스타일을 동적으로 조작할 수 있게 해줍니다. 하지만, DOM을 직접 조작하는 것은 성능 저하를 일으킬 수 있습니다. 특히, 많은 요소가 변경되는 경우, 브라우저는 이를 다시 렌더링해야 하므로 느려질 수 있습니다.

예제 코드: DOM 조작

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DOM Manipulation</title>
</head>
<body>
    <div id="app">Hello, World!</div> <!-- div 요소 -->
    <button id="updateButton">Update Text</button> <!-- 버튼 요소 -->

    <script>
        // 버튼 클릭 이벤트 리스너 추가
        document.getElementById('updateButton').addEventListener('click', function() {
            // 클릭 시 div 요소의 텍스트를 변경
            document.getElementById('app').textContent = 'Hello, Virtual DOM!';
        });
    </script>
</body>
</html>

위 예제는 버튼을 클릭하면 div 요소의 텍스트를 변경합니다. 작은 예제이지만, 많은 요소를 자주 변경해야 한다면 성능 문제가 발생할 수 있습니다.


2. 가상 DOM(Virtual DOM) 개념
가상 DOM은 실제 DOM의 가벼운 복사본입니다. 변경사항이 발생하면, 가상 DOM에서 먼저 업데이트를 수행하고, 그 후 실제 DOM과의 차이점을 최소화하여 한 번에 적용합니다. 이를 통해 실제 DOM 조작 횟수를 줄여 성능을 향상시킬 수 있습니다.

예제 코드: React를 사용한 가상 DOM

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function App() {
    // useState 훅을 사용하여 상태를 관리
    const [text, setText] = useState('Hello, World!');

    return (
        <div>
            <div>{text}</div> {/* 상태에 따라 텍스트를 표시 */}
            <button onClick={() => setText('Hello, Virtual DOM!')}>Update Text</button> {/* 버튼 클릭 시 상태 업데이트 */}
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById('root')); // ReactDOM을 사용하여 컴포넌트를 실제 DOM에 렌더링

위 예제는 React를 사용하여 동일한 작업을 수행합니다. 상태 변화에 따라 가상 DOM이 업데이트되고, 실제 DOM에 최소한의 변경사항만 반영됩니다.


3. 가상 DOM의 작동 원리
  1.초기 렌더링: 애플리케이션이 처음 렌더링될 때, 가상 DOM은 실제 DOM의 초기 상태를 반영합니다.
  2.변경 감지: 상태나 데이터가 변경되면, 가상 DOM에 새로운 트리를 생성합니다.
  3.비교: 변경된 가상 DOM 트리와 이전 가상 DOM 트리를 비교(diffing)합니다.
  4.패치: 비교 결과를 바탕으로 실제 DOM에 필요한 최소한의 변경사항만 적용(patching)합니다.


예제 코드: 가상 DOM의 작동 원리

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function DiffingExample() {
    const [items, setItems] = useState(['Item 1', 'Item 2']); // 상태로 항목 배열을 관리

    const updateItems = () => {
        setItems(['Item 1', 'Item 2', 'Item 3']); // 상태를 업데이트하여 새로운 항목 추가
    };

    return (
        <div>
            <ul>
                {items.map(item => <li key={item}>{item}</li>)} {/* 항목을 리스트로 렌더링 */}
            </ul>
            <button onClick={updateItems}>Add Item</button> {/* 버튼 클릭 시 항목 추가 */}
        </div>
    );
}

ReactDOM.render(<DiffingExample />, document.getElementById('root')); // 컴포넌트를 실제 DOM에 렌더링

위 예제는 가상 DOM의 diffing 과정을 설명합니다. items 배열에 새로운 항목이 추가되면, 가상 DOM은 변경된 부분을 감지하고 실제 DOM에 최소한의 변경사항만 반영합니다.

 


4. 가상 DOM의 장점

  • 성능 최적화: 최소한의 변경사항만 실제 DOM에 적용하여 불필요한 렌더링을 줄입니다.
  • 개발 용이성: 선언적 프로그래밍 방식으로 UI 업데이트를 쉽게 관리할 수 있습니다.
  • 재사용성: 컴포넌트 기반 구조를 사용하여 코드의 재사용성을 높입니다. 

예제 코드: 컴포넌트 재사용

import React from 'react';
import ReactDOM from 'react-dom';

function ListItem({ value }) {
    return <li>{value}</li>; // 항목을 렌더링하는 컴포넌트
}

function ItemList({ items }) {
    return (
        <ul>
            {items.map(item => <ListItem key={item} value={item} />)} {/* ListItem 컴포넌트를 사용하여 항목을 렌더링 */}
        </ul>
    );
}

const items = ['Item 1', 'Item 2', 'Item 3']; // 항목 배열

ReactDOM.render(<ItemList items={items} />, document.getElementById('root')); // ItemList 컴포넌트를 실제 DOM에 렌더링

위 예제는 컴포넌트 재사용의 예로, ListItem 컴포넌트를 ItemList 컴포넌트에서 재사용하여 각 항목을 렌더링합니다.


5. 가상 DOM을 사용하는 라이브러리
가상 DOM 개념은 여러 인기 있는 라이브러리에서 사용됩니다. 대표적으로 다음과 같은 라이브러리가 있습니다.

  • React: 가상 DOM을 도입한 가장 유명한 라이브러리로, 사용자 인터페이스를 구축하기 위해 컴포넌트 기반 접근 방식을 사용합니다.
  • Vue: React와 유사하게 가상 DOM을 사용하며, 반응형 데이터 바인딩과 컴포넌트 시스템을 제공합니다.
  • Preact: React와 비슷하지만 더 가벼운 버전으로, 가상 DOM을 사용하여 빠른 성능을 제공합니다.


예제 코드: Vue를 사용한 가상 DOM

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue를 사용한 가상 DOM</title>
</head>
<body>
    <div id="app">{{ message }}</div> <!-- Vue가 바인딩할 div 요소 -->
    <button @click="updateMessage">Update Text</button> <!-- 클릭 이벤트를 바인딩한 버튼 -->

    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script> <!-- Vue.js CDN -->
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'Hello, World!' // 초기 메시지
            },
            methods: {
                updateMessage() {
                    this.message = 'Hello, Virtual DOM!'; // 메시지 업데이트 메서드
                }
            }
        });
    </script>
</body>
</html>

위 예제는 Vue.js를 사용하여 div 요소의 텍스트를 변경합니다. Vue는 React와 마찬가지로 가상 DOM을 사용하여 효율적인 업데이트를 수행합니다.


6. 가상 DOM의 한계
가상 DOM에도 몇 가지 한계가 있습니다.

  • 초기 설정 비용: 가상 DOM을 사용하기 위해 초기 설정 및 학습이 필요합니다.
  • 메모리 사용: 가상 DOM 트리 유지에 따른 추가 메모리 사용이 발생할 수 있습니다.
  • 복잡성 증가: 매우 단순한 애플리케이션에서는 오히려 복잡성을 증가시킬 수 있습니다.

예제 코드: 단순한 애플리케이션에서의 복잡성

import React from 'react';
import ReactDOM from 'react-dom';

function SimpleApp() {
    return <div>Hello, World!</div>; // 단순한 텍스트를 표시하는 컴포넌트
}

ReactDOM.render(<SimpleApp />, document.getElementById('root')); // 컴포넌트를 실제 DOM에 렌더링

위 예제는 단순한 애플리케이션에서 가상 DOM을 사용하는 예로, 이 경우 가상 DOM의 복잡성이 오히려 불필요할 수 있습니다.


가상 DOM은 현대 웹 개발에서 필수적인 개념으로, 특히 대규모 애플리케이션에서 효율적인 성능을 제공합니다. React, Vue와 같은 라이브러리를 통해 가상 DOM의 장점을 쉽게 활용할 수 있으며, 이를 통해 빠르고 반응성 높은 웹 애플리케이션을 구축할 수 있습니다.

'공부 > JavaScript' 카테고리의 다른 글

JavaScript의 변수  (0) 2024.05.27
JavaScript Ajax이해하기  (0) 2024.05.22
JavaScript - 이벤트(Event)  (0) 2024.04.30