Deutsch

Ein umfassender Leitfaden zur Optimierung der React-Anwendungsleistung mit useMemo, useCallback und React.memo. Vermeiden Sie unnötige Neu-Renderings und verbessern Sie die Benutzererfahrung.

React-Leistungsoptimierung: useMemo, useCallback und React.memo meistern

React, eine beliebte JavaScript-Bibliothek zum Erstellen von Benutzeroberflächen, ist bekannt für seine komponentenbasierten Architektur und seinen deklarativen Stil. Wenn Anwendungen jedoch komplexer werden, kann die Leistung zu einem Problem werden. Unnötige Neu-Renderings von Komponenten können zu einer trägen Leistung und einer schlechten Benutzererfahrung führen. Glücklicherweise bietet React mehrere Tools zur Leistungsoptimierung, darunter useMemo, useCallback und React.memo. Dieser Leitfaden befasst sich mit diesen Techniken und bietet praktische Beispiele und umsetzbare Erkenntnisse, die Ihnen helfen, leistungsstarke React-Anwendungen zu erstellen.

React-Neu-Renderings verstehen

Bevor Sie in die Optimierungstechniken eintauchen, ist es entscheidend zu verstehen, warum Neu-Renderings in React auftreten. Wenn sich der Zustand oder die Props einer Komponente ändern, löst React ein Neu-Rendering dieser Komponente und potenziell ihrer Kindkomponenten aus. React verwendet ein virtuelles DOM, um das tatsächliche DOM effizient zu aktualisieren, aber übermäßige Neu-Renderings können die Leistung, insbesondere in komplexen Anwendungen, immer noch beeinträchtigen. Stellen Sie sich eine globale E-Commerce-Plattform vor, auf der Produktpreise häufig aktualisiert werden. Ohne Optimierung könnte selbst eine kleine Preisänderung Neu-Renderings über die gesamte Produktliste hinweg auslösen, was das Surfen des Benutzers beeinträchtigen würde.

Warum Komponenten neu rendern

Ziel der Leistungsoptimierung ist es, unnötige Neu-Renderings zu verhindern und sicherzustellen, dass Komponenten nur dann aktualisiert werden, wenn sich ihre Daten tatsächlich geändert haben. Betrachten Sie ein Szenario mit Echtzeit-Datenvisualisierung für die Börsenanalyse. Wenn die Diagrammkomponenten bei jeder geringfügigen Datenaktualisierung unnötigerweise neu rendern, wird die Anwendung nicht mehr reagieren. Die Optimierung von Neu-Renderings sorgt für eine reibungslose und reaktionsschnelle Benutzererfahrung.

Einführung in useMemo: Kostspielige Berechnungen memorisieren

useMemo ist ein React Hook, der das Ergebnis einer Berechnung memorisiert. Memoization ist eine Optimierungstechnik, die die Ergebnisse von kostspieligen Funktionsaufrufen speichert und diese Ergebnisse wiederverwendet, wenn dieselben Eingaben erneut auftreten. Dies verhindert die Notwendigkeit, die Funktion unnötigerweise erneut auszuführen.

Wann useMemo verwenden

Wie useMemo funktioniert

useMemo akzeptiert zwei Argumente:

  1. Eine Funktion, die die Berechnung durchführt.
  2. Ein Array von Abhängigkeiten.

Die Funktion wird nur ausgeführt, wenn sich eine der Abhängigkeiten im Array ändert. Andernfalls gibt useMemo den zuvor memorisierten Wert zurück.

Beispiel: Berechnung der Fibonacci-Sequenz

Die Fibonacci-Sequenz ist ein klassisches Beispiel für eine rechenintensive Berechnung. Erstellen wir eine Komponente, die die n-te Fibonacci-Zahl mit useMemo berechnet.


import React, { useState, useMemo } from 'react';

function Fibonacci({ n }) {
  const fibonacciNumber = useMemo(() => {
    console.log('Calculating Fibonacci...'); // Zeigt an, wann die Berechnung ausgeführt wird
    function calculateFibonacci(num) {
      if (num <= 1) {
        return num;
      }
      return calculateFibonacci(num - 1) + calculateFibonacci(num - 2);
    }
    return calculateFibonacci(n);
  }, [n]);

  return 

Fibonacci({n}) = {fibonacciNumber}

; } function App() { const [number, setNumber] = useState(5); return (
setNumber(parseInt(e.target.value))} />
); } export default App;

In diesem Beispiel wird die Funktion calculateFibonacci nur ausgeführt, wenn sich die Prop n ändert. Ohne useMemo würde die Funktion bei jedem Neu-Rendering der Fibonacci-Komponente ausgeführt, selbst wenn n gleich bliebe. Stellen Sie sich vor, diese Berechnung findet auf einem globalen Finanz-Dashboard statt – jeder Tick des Marktes würde eine vollständige Neuberechnung auslösen, was zu erheblichen Verzögerungen führen würde. useMemo verhindert das.

Einführung in useCallback: Funktionen memorisieren

useCallback ist ein weiterer React Hook, der Funktionen memorisiert. Er verhindert die Erstellung einer neuen Funktionsinstanz bei jedem Rendering, was besonders nützlich sein kann, wenn Callbacks als Props an Kindkomponenten übergeben werden.

Wann useCallback verwenden

Wie useCallback funktioniert

useCallback akzeptiert zwei Argumente:

  1. Die zu memorisierende Funktion.
  2. Ein Array von Abhängigkeiten.

Die Funktion wird nur neu erstellt, wenn sich eine der Abhängigkeiten im Array ändert. Andernfalls gibt useCallback dieselbe Funktionsinstanz zurück.

Beispiel: Handhabung eines Button-Klicks

Erstellen wir eine Komponente mit einem Button, der eine Callback-Funktion auslöst. Wir verwenden useCallback, um die Callback-Funktion zu memorisieren.


import React, { useState, useCallback } from 'react';

function Button({ onClick, children }) {
  console.log('Button re-rendered'); // Zeigt an, wann der Button neu rendert
  return ;
}

const MemoizedButton = React.memo(Button);

function App() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log('Button clicked');
    setCount((prevCount) => prevCount + 1);
  }, []); // Leeres Abhängigkeits-Array bedeutet, dass die Funktion nur einmal erstellt wird

  return (
    

Count: {count}

Inkrementieren
); } export default App;

In diesem Beispiel wird die Funktion handleClick nur einmal erstellt, da das Abhängigkeits-Array leer ist. Wenn die App-Komponente aufgrund der Zustandsänderung von count neu rendert, bleibt die Funktion handleClick dieselbe. Die mit React.memo umschlossene MemoizedButton-Komponente wird nur neu rendern, wenn sich ihre Props ändern. Da die onClick-Prop (handleClick) gleich bleibt, rendert die Button-Komponente nicht unnötigerweise neu. Stellen Sie sich eine interaktive Kartenanwendung vor. Jedes Mal, wenn ein Benutzer interagiert, könnten Dutzende von Button-Komponenten betroffen sein. Ohne useCallback würden diese Buttons unnötigerweise neu rendern, was zu einer trägen Erfahrung führen würde. Die Verwendung von useCallback sorgt für eine reibungslosere Interaktion.

Einführung in React.memo: Komponenten memorisieren

React.memo ist eine Higher-Order Component (HOC), die eine funktionale Komponente memorisiert. Sie verhindert, dass die Komponente neu rendert, wenn sich ihre Props nicht geändert haben. Dies ähnelt PureComponent für Klassenkomponenten.

Wann React.memo verwenden

Wie React.memo funktioniert

React.memo umschließt eine funktionale Komponente und vergleicht flach die vorherigen und nächsten Props. Wenn die Props gleich sind, wird die Komponente nicht neu rendern.

Beispiel: Anzeigen eines Benutzerprofils

Erstellen wir eine Komponente, die ein Benutzerprofil anzeigt. Wir verwenden React.memo, um unnötige Neu-Renderings zu verhindern, falls sich die Benutzerdaten nicht geändert haben.


import React from 'react';

function UserProfile({ user }) {
  console.log('UserProfile re-rendered'); // Zeigt an, wann die Komponente neu rendert
  return (
    

Name: {user.name}

Email: {user.email}

); } const MemoizedUserProfile = React.memo(UserProfile, (prevProps, nextProps) => { // Benutzerdefinierte Vergleichsfunktion (optional) return prevProps.user.id === nextProps.user.id; // Nur neu rendern, wenn sich die Benutzer-ID ändert }); function App() { const [user, setUser] = React.useState({ id: 1, name: 'John Doe', email: 'john.doe@example.com', }); const updateUser = () => { setUser({ ...user, name: 'Jane Doe' }); // Ändert den Namen }; return (
); } export default App;

In diesem Beispiel wird die MemoizedUserProfile-Komponente nur dann neu rendern, wenn sich die Prop user.id ändert. Selbst wenn sich andere Eigenschaften des user-Objekts ändern (z.B. der Name oder die E-Mail), wird die Komponente nicht neu rendern, es sei denn, die ID ist anders. Diese benutzerdefinierte Vergleichsfunktion innerhalb von `React.memo` ermöglicht eine feinkörnige Kontrolle darüber, wann die Komponente neu rendert. Betrachten Sie eine Social-Media-Plattform mit ständig aktualisierten Benutzerprofilen. Ohne `React.memo` würde eine Änderung des Benutzerstatus oder des Profilbildes ein vollständiges Neu-Rendering der Profilkomponente verursachen, selbst wenn die Kernbenutzerdetails gleich bleiben. `React.memo` ermöglicht gezielte Aktualisierungen und verbessert die Leistung erheblich.

Kombination von useMemo, useCallback und React.memo

Diese drei Techniken sind am effektivsten, wenn sie zusammen verwendet werden. useMemo memorisiert kostspielige Berechnungen, useCallback memorisiert Funktionen und React.memo memorisiert Komponenten. Durch die Kombination dieser Techniken können Sie die Anzahl unnötiger Neu-Renderings in Ihrer React-Anwendung erheblich reduzieren.

Beispiel: Eine komplexe Komponente

Erstellen wir eine komplexere Komponente, die zeigt, wie man diese Techniken kombiniert.


import React, { useState, useCallback, useMemo } from 'react';

function ListItem({ item, onUpdate, onDelete }) {
  console.log(`ListItem ${item.id} re-rendered`); // Zeigt an, wann die Komponente neu rendert
  return (
    
  • {item.text}
  • ); } const MemoizedListItem = React.memo(ListItem); function List({ items, onUpdate, onDelete }) { console.log('List re-rendered'); // Zeigt an, wann die Komponente neu rendert return (
      {items.map((item) => ( ))}
    ); } const MemoizedList = React.memo(List); function App() { const [items, setItems] = useState([ { id: 1, text: 'Item 1' }, { id: 2, text: 'Item 2' }, { id: 3, text: 'Item 3' }, ]); const handleUpdate = useCallback((id) => { setItems((prevItems) => prevItems.map((item) => item.id === id ? { ...item, text: `Aktualisiert ${item.text}` } : item ) ); }, []); const handleDelete = useCallback((id) => { setItems((prevItems) => prevItems.filter((item) => item.id !== id)); }, []); const memoizedItems = useMemo(() => items, [items]); return (
    ); } export default App;

    In diesem Beispiel:

    Diese Kombination von Techniken stellt sicher, dass die Komponenten nur bei Bedarf neu rendern, was zu erheblichen Leistungsverbesserungen führt. Stellen Sie sich ein groß angelegtes Projektmanagement-Tool vor, bei dem Aufgabenlisten ständig aktualisiert, gelöscht und neu angeordnet werden. Ohne diese Optimierungen würde jede kleine Änderung an der Aufgabenliste eine Kaskade von Neu-Renderings auslösen, wodurch die Anwendung langsam und unreagibel wird. Durch den strategischen Einsatz von useMemo, useCallback und React.memo kann die Anwendung auch bei komplexen Daten und häufigen Aktualisierungen performant bleiben.

    Zusätzliche Optimierungstechniken

    Obwohl useMemo, useCallback und React.memo mächtige Werkzeuge sind, sind sie nicht die einzigen Optionen zur Optimierung der React-Leistung. Hier sind einige weitere Techniken, die Sie in Betracht ziehen sollten:

    Globale Überlegungen zur Optimierung

    Bei der Optimierung von React-Anwendungen für ein globales Publikum ist es wichtig, Faktoren wie Netzwerklatenz, Gerätefähigkeiten und Lokalisierung zu berücksichtigen. Hier sind einige Tipps:

    Fazit

    Die Optimierung der React-Anwendungsleistung ist entscheidend für eine reibungslose und reaktionsschnelle Benutzererfahrung. Durch die Beherrschung von Techniken wie useMemo, useCallback und React.memo sowie durch die Berücksichtigung globaler Optimierungsstrategien können Sie leistungsstarke React-Anwendungen erstellen, die den Anforderungen einer vielfältigen Benutzerbasis gerecht werden. Denken Sie daran, Ihre Anwendung zu profilieren, um Leistungsengpässe zu identifizieren und diese Optimierungstechniken strategisch anzuwenden. Optimieren Sie nicht zu früh – konzentrieren Sie sich auf Bereiche, in denen Sie die größte Wirkung erzielen können.

    Dieser Leitfaden bietet eine solide Grundlage für das Verständnis und die Implementierung von React-Leistungsoptimierungen. Während Sie weiterhin React-Anwendungen entwickeln, denken Sie daran, die Leistung zu priorisieren und kontinuierlich nach neuen Wegen zu suchen, um die Benutzererfahrung zu verbessern.