Beim Erstellen moderner Webanwendungen ist eine effiziente Aktualisierung der Benutzeroberfläche (UI) unerlässlich, um Apps schnell und reaktionsfähig zu halten. Eine in vielen Frameworks (wie React) häufig verwendete Strategie besteht darin, ein virtuelles DOM und Komponenten zu verwenden. In diesem Artikel wird erklärt, wie Komponenten mithilfe eines virtuellen DOM gerendert werden und wie wir das erneute Rendern optimieren können, damit die Web-App nicht langsam wird.
Das DOM (Document Object Model) ist eine baumartige Struktur, die alle Elemente auf einer Webseite darstellt. Jedes Mal, wenn Sie mit einer Webseite interagieren – auf Schaltflächen klicken, Text eingeben – muss der Browser das DOM aktualisieren, was langsam sein kann.
Ein virtuelles DOM ist wie eine Kopie des echten DOM, lebt aber nur im Speicher. Anstatt das reale DOM jedes Mal direkt zu aktualisieren, wenn sich etwas ändert, aktualisieren wir zuerst das virtuelle DOM. Sobald Änderungen vorgenommen werden, vergleicht sich das virtuelle DOM mit der alten Version, findet die Unterschiede (dies wird als Unterschiede bezeichnet) und aktualisiert nur die Teile des realen DOM, die geändert werden müssen.
In einer modernen Web-App sind Komponenten die Bausteine der Benutzeroberfläche. Betrachten Sie sie als kleine, wiederverwendbare Teile einer Webseite. Zum Beispiel:
Jede Komponente beschreibt, wie ein Teil der Benutzeroberfläche aussehen soll. Eine Komponentenfunktion gibt einen virtuellen DOM-Baum zurück, der diese Benutzeroberfläche darstellt.
Lassen Sie uns eine einfache Button-Komponente mit Pseudocode erstellen. Diese Komponente gibt eine Schaltfläche mit Text und eine Funktion zurück, die ausgeführt wird, wenn auf die Schaltfläche geklickt wird.
// Component to display a button function Button(props) { // The Button component returns a Virtual DOM node for a
In diesem Beispiel:
Angenommen, wir möchten eine App erstellen, die einen Header und eine Schaltfläche hat. Jeder dieser Teile kann als Komponenten dargestellt werden. Der Aufbau der App könnte so aussehen:
// 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!") }
Wenn die App zum ersten Mal ausgeführt wird:
// 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 }
Nehmen wir an, dass sich etwas in der App ändert, beispielsweise der Schaltflächentext. Normalerweise würde die gesamte App neu gerendert, dies kann jedoch langsam sein, wenn die App groß ist. Stattdessen können wir das erneute Rendern optimieren, indem wir nur die Teile aktualisieren, die sich geändert haben.
Folgendes passiert, wenn ein erneutes Rendern erfolgt:
Angenommen, der Text der Schaltfläche ändert sich von „Click Me“ zu „Clicked!“. So würden wir die Schaltfläche neu rendern:
// 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)
Eine der wichtigsten Möglichkeiten zur Optimierung des erneuten Renderns besteht darin, zu prüfen, ob eine Komponente tatsächlich aktualisiert werden muss. Wenn sich an den props oder dem state der Komponente nichts geändert hat, können wir das erneute Rendern dieser Komponente überspringen. Hier kommt die Logik shouldComponentUpdate ins Spiel.
// Function to check if a component should update function shouldComponentUpdate(oldProps, newProps) { return oldProps !== newProps // Only update if the props have changed }
Jetzt prüfen wir vor dem erneuten Rendern, ob die Komponente aktualisiert werden soll:
// Example: Optimized re-rendering of Button component function renderButtonIfNeeded(oldButton, newButton) { if (shouldComponentUpdate(oldButton.props, newButton.props)) { let realButton = createRealDOM(newButton) patch(realButton) } }
Beim Rendern von Elementlisten (z. B. einer Liste von Schaltflächen) können wir optimieren, indem wir Tasten verwenden, um jedes Element eindeutig zu identifizieren. Dies hilft dem Differenzierungsalgorithmus, alte und neue Elemente in der Liste abzugleichen und nur die notwendigen Änderungen anzuwenden.
// 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 }) )) }
Wenn sich mit den Tasten eines der Elemente in der Liste ändert (z. B. das Hinzufügen oder Entfernen einer Schaltfläche), kann der Algorithmus schnell erkennen, welche Schaltfläche sich geändert hat, und nur diese aktualisieren.
Komponenten können auch ihren eigenen Zustand haben. Wenn sich der Status einer Komponente ändert, möchten wir nur diese bestimmte Komponente neu rendern, nicht die gesamte App. Hier ist ein Beispiel für eine Schaltfläche mit dem Status:
// 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"]) }
In diesem Fall:
Eine weitere Optimierung besteht darin, das erneute Rendern übergeordneter Komponenten zu vermeiden, wenn sich nur eine untergeordnete Komponente ändert. Wenn sich beispielsweise die Schaltfläche ändert, der Header jedoch gleich bleibt, können wir das erneute Rendern des Headers überspringen.
// 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 ]) }
Zusammenfassend können wir den Prozess des Renderns und Optimierens von Komponenten mithilfe des virtuellen DOM in folgende Schritte unterteilen:
Indem wir sorgfältig darüber nachdenken, wann und was neu gerendert werden soll, können wir sicherstellen, dass Webanwendungen auch bei zunehmender Komplexität effizient bleiben. Das Virtual DOM ist ein leistungsstarkes Tool, das dabei hilft, dieses Gleichgewicht zwischen Einfachheit und Leistung zu erreichen!
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3