«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как компоненты визуализируются в виртуальном DOM и как оптимизировать повторный рендеринг

Как компоненты визуализируются в виртуальном DOM и как оптимизировать повторный рендеринг

Опубликовано 7 ноября 2024 г.
Просматривать:939

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

При создании современных веб-приложений эффективное обновление пользовательского интерфейса (пользовательский интерфейс) имеет важное значение для обеспечения быстрого и оперативного реагирования приложений. Общая стратегия, используемая во многих фреймворках (например, React), заключается в использовании Виртуального DOM и компонентов. В этой статье объясняется, как компоненты визуализируются с использованием Virtual DOM и как мы можем оптимизировать повторный рендеринг, чтобы веб-приложение не работало медленно.

1. Что такое виртуальный DOM?

DOM (объектная модель документа) — это древовидная структура, которая представляет все элементы веб-страницы. Каждый раз, когда вы взаимодействуете с веб-страницей — нажимаете кнопки, вводите текст — браузеру приходится обновлять DOM, что может быть медленным.

Виртуальный DOM похож на копию реального DOM, но живет только в памяти. Вместо того, чтобы обновлять реальный DOM напрямую каждый раз, когда что-то меняется, мы сначала обновляем виртуальный DOM. После внесения изменений виртуальный DOM сравнивает себя со старой версией, находит различия (это называется diffing) и обновляет только те части реального DOM, которые необходимо изменить.

2. Что такое компоненты?

В современном веб-приложении компоненты являются строительными блоками пользовательского интерфейса. Думайте о них как о небольших, многократно используемых частях веб-страницы. Например:

  • Кнопка может быть компонентом.
  • заголовок может быть компонентом.
  • список элементов может быть компонентом.

Каждый компонент описывает, как должна выглядеть часть пользовательского интерфейса. компонентная функция возвращает дерево виртуального DOM, которое представляет этот пользовательский интерфейс.

3. Пример: создание компонента кнопки

Давайте создадим простой компонент Кнопка с использованием псевдокода. Этот компонент вернет кнопку с текстом и функцию, которая запускается при нажатии кнопки.

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

В этом примере:

  • Компонент Button принимает props (свойства), например текст кнопки и обработчик событий при ее нажатии.
  • Он возвращает узел Virtual DOM, который представляет элемент

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!")
}
  • Компонент App возвращает Виртуальное дерево DOM, содержащее два компонента: заголовок и кнопку.
  • Компонент Header возвращает узел Virtual DOM, представляющий элемент

    .

  • Компонент «Кнопка» работает, как мы описали ранее.

5. Как работает первоначальный рендеринг

При первом запуске приложения оно:

  1. Вызывает компоненты: выполняются App(), Header() и Button().
  2. Создает виртуальный DOM: результатом является дерево узлов виртуального DOM, представляющее пользовательский интерфейс.
  3. Обновляет настоящий DOM: виртуальный DOM используется для создания реальных элементов HTML в реальном DOM.
// 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. Различия: сравниваем старый Virtual DOM с новым и выясняем, что изменилось.
  2. Исправление: изменяются только те части реального DOM, которые необходимо обновить (этот процесс называется исправлением).

Пример: изменение текста кнопки

Предположим, текст кнопки изменится с «Нажмите на меня» на «Нажали!». Вот как мы будем перерисовывать кнопку:

// 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 или state компонента ничего не изменилось, мы можем пропустить повторный рендеринг этого компонента. Здесь на помощь приходит логика 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

Подводя итог, мы можем разбить процесс рендеринга и оптимизации компонентов с использованием Virtual DOM на следующие этапы:

  1. Первоначальный рендеринг: при первом рендеринге приложения мы создаем дерево виртуального DOM и преобразуем его в настоящий DOM.
  2. Повторный рендеринг: когда что-то меняется (например, текст или состояние кнопки), мы обновляем виртуальный DOM и применяем только необходимые изменения к реальному DOM.
  3. Оптимизация повторного рендеринга: используя такие стратегии, как mustComponentUpdate, ключи для списков и обновления на основе состояния, мы можем избежать ненужного повторного рендеринга, сохраняя при этом быстроту и отзывчивость приложения.

Тщательно продумывая, когда и что нужно перерисовывать, мы можем гарантировать, что веб-приложения останутся эффективными, даже если они усложнятся. 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