"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 가상 DOM에서 구성 요소가 렌더링되는 방법 및 다시 렌더링을 최적화하는 방법

가상 DOM에서 구성 요소가 렌더링되는 방법 및 다시 렌더링을 최적화하는 방법

2024-11-07에 게시됨
검색:742

How Components are Rendered in a Virtual DOM and How to Optimize Re-Rendering

최신 웹 애플리케이션을 구축할 때 앱의 속도와 반응성을 유지하려면 UI(사용자 인터페이스)를 효율적으로 업데이트하는 것이 필수적입니다. React와 같은 많은 프레임워크에서 사용되는 일반적인 전략은 가상 DOM구성 요소를 사용하는 것입니다. 이 문서에서는 가상 DOM을 사용하여 구성 요소를 렌더링하는 방법과 웹 앱이 느려지지 않도록 재렌더링을 최적화하는 방법에 대해 설명합니다.

1. 가상 DOM이란 무엇입니까?

DOM(문서 객체 모델)은 웹페이지의 모든 요소를 ​​나타내는 트리형 구조입니다. 버튼 클릭, 텍스트 입력 등 웹페이지와 상호 작용할 때마다 브라우저는 DOM을 업데이트해야 하므로 속도가 느려질 수 있습니다.

가상 DOM은 실제 DOM의 복사본과 같지만 메모리에만 존재합니다. 무언가 변경될 때마다 실제 DOM을 직접 업데이트하는 대신 Virtual DOM을 먼저 업데이트합니다. 변경이 이루어지면 가상 DOM은 이전 버전과 자신을 비교하여 차이점을 찾고(이를 차이라고 함) 변경이 필요한 실제 DOM 부분만 업데이트합니다.

2. 구성요소란 무엇입니까?

최신 웹 앱에서 구성 요소는 UI의 구성 요소입니다. 웹페이지의 작고 재사용 가능한 부분이라고 생각하세요. 예를 들어:

  • 버튼은 구성 요소가 될 수 있습니다.
  • 헤더는 구성 요소가 될 수 있습니다.
  • 항목 목록은 구성 요소가 될 수 있습니다.

각 구성요소는 UI의 어떤 부분이 보여야 하는지 설명합니다. 구성요소 함수는 해당 UI를 나타내는 가상 DOM 트리를 반환합니다.

3. 예: 버튼 구성요소 생성

의사 코드를 사용하여 간단한 버튼 구성 요소를 만들어 보겠습니다. 이 구성요소는 텍스트가 포함된 버튼과 버튼을 클릭할 때 실행되는 함수를 반환합니다.

// Component to display a button
function Button(props) {
    // The Button component returns a Virtual DOM node for a 

이 예에서는:

  • 버튼 구성요소는 버튼 텍스트 및 클릭 시 이벤트 핸들러와 같은 소품(속성)을 사용합니다.
  • 제공된 텍스트와 onClick 이벤트 핸들러가 있는

4. 여러 구성 요소 렌더링

헤더버튼이 있는 앱을 만들고 싶다고 가정해 보겠습니다. 이러한 각 부분은 구성 요소로 표시될 수 있습니다. 앱의 구조는 다음과 같습니다:

// App component with a header and button
function App() {
    return new VirtualNode("div", {}, [
        new Header(), // The Header component
        new Button({ text: "Click Me", onClick: handleClick }) // The Button component
    ])
}

// Header component
function Header() {
    return new VirtualNode("h1", {}, ["Welcome to the App!"])
}

// Function to handle button clicks
function handleClick() {
    console.log("Button clicked!")
}
  • 앱 구성요소는 헤더와 버튼이라는 두 구성요소를 포함하는 가상 DOM 트리를 반환합니다.
  • 헤더 구성요소는

    요소를 나타내는 가상 DOM 노드를 반환합니다.

  • 버튼 구성요소는 앞에서 설명한 대로 작동합니다.

5. 초기 렌더링 작동 방식

앱이 처음 실행되면 다음이 수행됩니다.

  1. 컴포넌트 호출: App(), Header(), Button()이 실행됩니다.
  2. 가상 DOM 생성: 결과는 UI를 나타내는 가상 DOM 노드 트리입니다.
  3. 실제 DOM 업데이트: 가상 DOM은 실제 DOM에 실제 HTML 요소를 구축하는 데 사용됩니다.
// Initial render of the app
function renderApp() {
    let virtualDOM = App()          // Render the app's Virtual DOM
    let realDOM = createRealDOM(virtualDOM)  // Convert the Virtual DOM into real DOM elements
    attachToPage(realDOM)           // Attach the real DOM elements to the webpage
}

6. 리렌더링과 최적화가 필요한 이유

버튼 텍스트와 같이 앱에서 뭔가가 변경된다고 가정해 보겠습니다. 일반적으로 전체 앱이 다시 렌더링되지만 앱이 크면 속도가 느려질 수 있습니다. 대신 변경된 부분만 업데이트하여 재렌더링을 최적화할 수 있습니다.

다시 렌더링이 발생하면 다음과 같은 일이 발생합니다.

  1. 비교: 이전 가상 DOM과 새 가상 DOM을 비교하고 무엇이 변경되었는지 파악합니다.
  2. 패칭: 업데이트가 필요한 실제 DOM 부분만 변경됩니다(이 프로세스를 패칭이라고 함).

예: 버튼 텍스트 변경

버튼 텍스트가 "Click Me"에서 "Clicked!"로 변경되었다고 가정해 보겠습니다. 버튼을 다시 렌더링하는 방법은 다음과 같습니다.

// New Button component with updated text
function Button(props) {
    return new VirtualNode("button", { onClick: props.onClick }, [props.text])
}

// Re-rendering with the new text
let oldButton = Button({ text: "Click Me", onClick: handleClick })
let newButton = Button({ text: "Clicked!", onClick: handleClick })

// Diff the old and new Button
let diffResult = diff(oldButton, newButton)

// Patch the real DOM with the changes
patch(realButtonDOM, diffResult)

7. 재렌더링 최적화: 구성요소 업데이트 필요

재렌더링을 최적화하는 주요 방법 중 하나는 구성 요소를 실제로 업데이트해야 하는지 확인하는 것입니다. 구성 요소의 props 또는 상태에 변경된 사항이 없으면 해당 구성 요소를 다시 렌더링하는 작업을 건너뛸 수 있습니다. 이것이 shouldComponentUpdate 로직이 들어오는 곳입니다.

// Function to check if a component should update
function shouldComponentUpdate(oldProps, newProps) {
    return oldProps !== newProps // Only update if the props have changed
}

이제 다시 렌더링하기 전에 구성요소를 업데이트해야 하는지 확인합니다.

// Example: Optimized re-rendering of Button component
function renderButtonIfNeeded(oldButton, newButton) {
    if (shouldComponentUpdate(oldButton.props, newButton.props)) {
        let realButton = createRealDOM(newButton)
        patch(realButton)
    }
}

8. 목록 최적화를 위한 키 사용

항목 목록(예: 버튼 목록)을 렌더링할 때 를 사용하여 각 항목을 고유하게 식별함으로써 최적화할 수 있습니다. 이는 비교 알고리즘이 목록의 이전 항목과 새 항목을 일치시키고 필요한 변경 사항만 적용하는 데 도움이 됩니다.

// List of buttons with unique keys
function ButtonList(items) {
    return new VirtualNode("div", {}, items.map(item => 
        new Button({ key: item.id, text: item.text, onClick: handleClick })
    ))
}

를 사용하면 목록의 항목 중 하나가 변경되면(예: 버튼 추가 또는 제거) 알고리즘이 어떤 버튼이 변경되었는지 빠르게 식별하고 해당 버튼만 업데이트할 수 있습니다.

9. 상태 변경 최적화

구성요소는 자체 상태를 가질 수도 있습니다. 구성 요소의 상태가 변경되면 전체 앱이 아닌 특정 구성 요소만 다시 렌더링하려고 합니다. 다음은 상태가 있는 버튼의 예입니다.

// Button component with state
function ButtonWithState() {
    let [clicked, setClicked] = useState(false) // Create state for button

    function handleClick() {
        setClicked(true) // Update state when clicked
    }

    return new VirtualNode("button", { onClick: handleClick }, [clicked ? "Clicked!" : "Click Me"])
}

이 경우:

  • 클릭하면 버튼 텍스트가 변경됩니다.
  • ButtonWithState 구성요소만 다시 렌더링되며 실제 DOM은 버튼 텍스트만 업데이트합니다.

10. 상위 구성 요소를 다시 렌더링하지 마세요.

또 다른 최적화는 하위 구성 요소만 변경될 때 상위 구성 요소를 다시 렌더링하지 않는 것입니다. 예를 들어 버튼이 변경되었지만 헤더가 동일하게 유지되는 경우 헤더 다시 렌더링을 건너뛸 수 있습니다.

// Optimized App component
function App() {
    if (!shouldComponentUpdate(oldHeaderProps, newHeaderProps)) {
        return oldHeader // Reuse the old Header if it hasn't changed
    }

    return new VirtualNode("div", {}, [
        new Header(), // Re-render the Header only if necessary
        new ButtonWithState() // Button re-renders based on state
    ])
}

11. 결론: 가상 DOM을 통한 효율적인 UI 업데이트

요약하자면 Virtual DOM을 사용하여 구성 요소를 렌더링하고 최적화하는 프로세스를 다음 단계로 나눌 수 있습니다.

  1. 초기 렌더링: 앱이 처음 렌더링될 때 가상 DOM 트리를 구축하고 이를 실제 DOM으로 변환합니다.
  2. 재렌더링: 무언가 변경되면(버튼 텍스트나 상태 등) 가상 DOM을 업데이트하고 필요한 변경 사항만 실제 DOM에 적용합니다.
  3. 재렌더링 최적화: shouldComponentUpdate, 목록용 키, 상태 기반 업데이트와 같은 전략을 사용하면 불필요한 재렌더링을 방지하고 앱의 속도와 반응성을 유지할 수 있습니다.

언제 무엇을 다시 렌더링할지 신중하게 생각함으로써 웹 애플리케이션이 복잡해지더라도 효율성을 유지할 수 있습니다. Virtual DOM은 단순성과 성능 사이의 균형을 유지하는 데 도움이 되는 강력한 도구입니다!

릴리스 선언문 이 기사는 https://dev.to/biswasprasana001/how-comComponents-are-rendered-in-a-virtual-dom-and-how-to-optimize-re-rendering-5f61?1에 재현되어 있습니다. 침해, 삭제하려면 [email protected]으로 문의하세요.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3