Lors de la création d'applications Web modernes, la mise à jour efficace de l'interface utilisateur (interface utilisateur) est essentielle pour que les applications restent rapides et réactives. Une stratégie courante utilisée dans de nombreux frameworks (comme React) consiste à utiliser un DOM virtuel et des composants. Cet article expliquera comment les composants sont rendus à l'aide d'un DOM virtuel et comment nous pouvons optimiser le nouveau rendu afin que l'application Web ne devienne pas lente.
Le DOM (Document Object Model) est une structure arborescente qui représente tous les éléments d'une page Web. Chaque fois que vous interagissez avec une page Web (en cliquant sur des boutons, en tapant du texte), le navigateur doit mettre à jour le DOM, ce qui peut être lent.
Un DOM virtuel est comme une copie du vrai DOM mais ne vit qu'en mémoire. Au lieu de mettre à jour le DOM réel directement à chaque fois que quelque chose change, nous mettons d'abord à jour le DOM virtuel. Une fois les modifications apportées, le DOM virtuel se compare à l'ancienne version, trouve les différences (c'est ce qu'on appelle diffing) et met à jour uniquement les parties du DOM réel qui doivent être modifiées.
Dans une application Web moderne, les composants sont les éléments constitutifs de l'interface utilisateur. Considérez-les comme de petites parties réutilisables d’une page Web. Par exemple:
Chaque composant décrit à quoi devrait ressembler une partie de l'interface utilisateur. Une fonction de composant renvoie une arborescence DOM virtuel qui représente cette interface utilisateur.
Créons un simple composant Button en utilisant un pseudocode. Ce composant renverra un bouton avec du texte et une fonction qui s'exécute lorsque vous cliquez sur le bouton.
// Component to display a button function Button(props) { // The Button component returns a Virtual DOM node for a
Dans cet exemple :
Disons que nous voulons créer une application dotée d'un en-tête et d'un bouton. Chacune de ces parties peut être représentée comme des composants. La structure de l'application pourrait ressembler à ceci :
// 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!") }
Lorsque l'application s'exécute pour la première fois, elle :
// 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 }
Disons que quelque chose change dans l'application, comme le texte du bouton. Normalement, l'intégralité de l'application serait restituée, mais cela peut être lent si l'application est volumineuse. Au lieu de cela, nous pouvons optimiser le nouveau rendu en mettant à jour uniquement les parties qui ont changé.
Voici ce qui se passe lors du nouveau rendu :
Disons que le texte du bouton passe de « Cliquez sur moi » à « Cliqué ! ». Voici comment nous restituerions le bouton :
// 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)
L'un des principaux moyens d'optimiser le rendu consiste à vérifier si un composant doit réellement être mis à jour. Si rien n'a changé dans les props ou state du composant, nous pouvons ignorer le nouveau rendu de ce composant. C'est là qu'intervient la logique shouldComponentUpdate.
// Function to check if a component should update function shouldComponentUpdate(oldProps, newProps) { return oldProps !== newProps // Only update if the props have changed }
Maintenant, avant de refaire le rendu, nous vérifions si le composant doit être mis à jour :
// Example: Optimized re-rendering of Button component function renderButtonIfNeeded(oldButton, newButton) { if (shouldComponentUpdate(oldButton.props, newButton.props)) { let realButton = createRealDOM(newButton) patch(realButton) } }
Lors du rendu de listes d'éléments (par exemple, une liste de boutons), nous pouvons optimiser en utilisant des touches pour identifier de manière unique chaque élément. Cela aide l'algorithme de comparaison à faire correspondre les anciens et les nouveaux éléments de la liste et à appliquer uniquement les modifications nécessaires.
// 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 }) )) }
Avec touches, si l'un des éléments de la liste change (comme l'ajout ou la suppression d'un bouton), l'algorithme peut rapidement identifier quel bouton a changé et mettre à jour uniquement celui-là.
Les composants peuvent également avoir leur propre état. Lorsque l'état d'un composant change, nous souhaitons uniquement restituer ce composant spécifique, pas l'ensemble de l'application. Voici un exemple de bouton avec état :
// 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"]) }
Dans ce cas:
Une autre optimisation consiste à éviter de restituer les composants parents lorsque seul un composant enfant change. Par exemple, si le bouton change mais que l'en-tête reste le même, nous pouvons ignorer le nouveau rendu de l'en-tête.
// 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 ]) }
Pour résumer, nous pouvons décomposer le processus de rendu et d'optimisation des composants à l'aide du DOM virtuel en ces étapes :
En réfléchissant soigneusement au moment et aux éléments à restituer, nous pouvons nous assurer que les applications Web restent efficaces même si leur complexité augmente. Le Virtual DOM est un outil puissant qui permet d'atteindre cet équilibre entre simplicité et performances !
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3