При создании современных веб-приложений эффективное обновление пользовательского интерфейса (пользовательский интерфейс) имеет важное значение для обеспечения быстрого и оперативного реагирования приложений. Общая стратегия, используемая во многих фреймворках (например, React), заключается в использовании Виртуального DOM и компонентов. В этой статье объясняется, как компоненты визуализируются с использованием Virtual DOM и как мы можем оптимизировать повторный рендеринг, чтобы веб-приложение не работало медленно.
DOM (объектная модель документа) — это древовидная структура, которая представляет все элементы веб-страницы. Каждый раз, когда вы взаимодействуете с веб-страницей — нажимаете кнопки, вводите текст — браузеру приходится обновлять DOM, что может быть медленным.
Виртуальный DOM похож на копию реального DOM, но живет только в памяти. Вместо того, чтобы обновлять реальный DOM напрямую каждый раз, когда что-то меняется, мы сначала обновляем виртуальный DOM. После внесения изменений виртуальный DOM сравнивает себя со старой версией, находит различия (это называется diffing) и обновляет только те части реального DOM, которые необходимо изменить.
В современном веб-приложении компоненты являются строительными блоками пользовательского интерфейса. Думайте о них как о небольших, многократно используемых частях веб-страницы. Например:
Каждый компонент описывает, как должна выглядеть часть пользовательского интерфейса. компонентная функция возвращает дерево виртуального DOM, которое представляет этот пользовательский интерфейс.
Давайте создадим простой компонент Кнопка с использованием псевдокода. Этот компонент вернет кнопку с текстом и функцию, которая запускается при нажатии кнопки.
// Component to display a button function Button(props) { // The Button component returns a Virtual DOM node for a
В этом примере:
Предположим, мы хотим создать приложение, которое имеет заголовок и кнопку. Каждую из этих частей можно представить в виде компонентов. Структура приложения может выглядеть так:
// 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!") }
При первом запуске приложения оно:
// 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 }
Допустим, что-то в приложении изменилось, например текст кнопки. Обычно все приложение будет перерисовано, но это может быть медленно, если приложение большое. Вместо этого мы можем оптимизировать повторный рендеринг, обновляя только те части, которые изменились.
Вот что происходит при повторной отрисовке:
Предположим, текст кнопки изменится с «Нажмите на меня» на «Нажали!». Вот как мы будем перерисовывать кнопку:
// 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)
Один из ключевых способов оптимизации повторного рендеринга — проверка того, действительно ли компонент нуждается в обновлении. Если в 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) } }
При рендеринге списков элементов (например, списка кнопок) мы можем оптимизировать их, используя ключи для уникальной идентификации каждого элемента. Это помогает алгоритму сравнения сопоставлять старые и новые элементы в списке и применять только необходимые изменения.
// 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 }) )) }
С помощью клавиш если один из элементов в списке изменяется (например, добавляется или удаляется кнопка), алгоритм может быстро определить, какая кнопка изменилась, и обновить только эту.
Компоненты также могут иметь собственное состояние. Когда состояние компонента меняется, мы хотим перерисовать только этот конкретный компонент, а не все приложение. Вот пример кнопки с состоянием:
// 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"]) }
В этом случае:
Другая оптимизация заключается в том, чтобы избежать повторного рендеринга родительских компонентов, когда изменяется только дочерний компонент. Например, если кнопка изменится, но заголовок останется прежним, мы можем пропустить повторную отрисовку заголовка.
// 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 ]) }
Подводя итог, мы можем разбить процесс рендеринга и оптимизации компонентов с использованием Virtual DOM на следующие этапы:
Тщательно продумывая, когда и что нужно перерисовывать, мы можем гарантировать, что веб-приложения останутся эффективными, даже если они усложнятся. Virtual DOM — мощный инструмент, который помогает достичь баланса между простотой и производительностью!
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3