Codeaufteilung mit React.lazy und Suspense

Sie müssen nie mehr Code als nötig an Ihre Nutzer senden. Teilen Sie Ihre Sets auf, damit so etwas nie passiert.

Mit der Methode React.lazy wird das Aufteilen einer React-Anwendung auf einem Komponentenebene mithilfe dynamischer Importe erstellen.

import React, { lazy } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));

const DetailsComponent = () => (
  <div>
    <AvatarComponent />
  </div>
)

Welchen Nutzen bieten sie?

Eine große React-Anwendung besteht in der Regel aus vielen Methoden und Bibliotheken von Drittanbietern. Wenn Sie nicht versuchen, verschiedenen Teilen einer Anwendung nur dann nutzen, wenn sie benötigt werden, Das JavaScript-Bundle wird an Ihre Nutzer gesendet, sobald diese das auf der ersten Seite. Dies kann die Seitenleistung erheblich beeinträchtigen.

Die Funktion React.lazy bietet eine integrierte Möglichkeit zum Trennen von Komponenten in einem mit geringem Aufwand in separate JavaScript-Blöcke unterteilt. Sie können und übernehmen die Ladestatus, wenn du es mit dem Suspense koppelst Komponente.

Spannung

Das Problem beim Versand einer großen JavaScript-Nutzlast an Nutzer wie lange es dauern würde, bis die Seite vollständig geladen ist, insbesondere auf schwächeren Geräten. und Netzwerkverbindungen. Deshalb sind Codeaufteilung und Lazy Loading äußerst nützlich.

Es gibt jedoch immer eine leichte Verzögerung. wird eine Code-Split-Komponente über das Netzwerk abgerufen, daher ist es wichtig, einen nützlichen Ladestatus anzuzeigen. React.lazy mit Suspense verwenden Komponente hilft, dieses Problem zu lösen.

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));

const renderLoader = () => <p>Loading</p>;

const DetailsComponent = () => (
  <Suspense fallback={renderLoader()}>
    <AvatarComponent />
  </Suspense>
)

Suspense akzeptiert eine fallback-Komponente, mit der du beliebige Reacts anzeigen lassen kannst Komponente als Ladezustand. Das folgende Beispiel zeigt, wie das funktioniert. Der Avatar wird nur gerendert, wenn auf die Schaltfläche geklickt wird, wenn eine Anfrage wird dann ausgeführt, um den für das gesperrte AvatarComponent erforderlichen Code abzurufen. In der Zwischenzeit wird die Komponente für das Laden des Fallbacks angezeigt.

Hier ist der Code, aus dem AvatarComponent besteht, klein. warum das Ladesymbol nur für kurze Zeit angezeigt wird. Größer das Laden von Komponenten sehr viel länger dauern kann, schwache Netzwerkverbindung.

Zur besseren Veranschaulichung der Funktionsweise:

  • Wenn Sie sich eine Vorschau der Website ansehen möchten, klicken Sie auf App ansehen. Drücken Sie dann Vollbild Vollbild
  • Drücken Sie „Strg + Umschalttaste + J“ (oder „Befehlstaste + Option + J“ auf einem Mac), um die Entwicklertools zu öffnen.
  • Klicken Sie auf den Tab Netzwerk.
  • Klicken Sie auf das Drop-down-Menü Drosselung, das standardmäßig auf Keine Drosselung eingestellt ist. Wählen Sie Schnelles 3G aus.
  • Klicken Sie in der App auf die Schaltfläche Click Me.

Die Ladeanzeige wird jetzt länger angezeigt. Sie sehen, dass der gesamte Code, aus der AvatarComponent wird als separater Block abgerufen.

<ph type="x-smartling-placeholder">
</ph> Netzwerkbereich in Entwicklertools, in dem eine Chunk.js-Datei heruntergeladen wird

Mehrere Komponenten anhalten

Eine weitere Funktion von Suspense besteht darin, dass Sie mehrere auch bei Lazy Loading.

Beispiel:

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));

const renderLoader = () => <p>Loading</p>;

const DetailsComponent = () => (
  <Suspense fallback={renderLoader()}>
    <AvatarComponent />
    <InfoComponent />
    <MoreInfoComponent />
  </Suspense>
)

Dies ist eine äußerst nützliche Methode, um das Rendern mehrerer Komponenten zu verzögern, während nur ein einziger Ladestatus angezeigt wird. Sobald alle Komponenten fertiggestellt sind, kann der Nutzer sie alle gleichzeitig sehen.

Sie können dies mit folgender Einbettung sehen:

Andernfalls kann es leicht zum Problem des gestaffelten Ladens kommen verschiedene Teile einer Benutzeroberfläche, die nacheinander geladen werden, wobei jeder eine eigene hat Ladeanzeige. Dies kann dazu führen, dass die User Experience unübersichtlicher wird.

Fehler beim Laden beheben

Mit Suspense kannst du einen temporären Ladestatus anzeigen lassen, während die Netzwerkverbindung Anfragen im Hintergrund erfolgen. Was aber, wenn diese Netzwerkanfragen aus irgendeinem Grund? Möglicherweise sind Sie offline oder Ihre Web-App versucht, Lazy Loading für eine versionierte URL die veraltet und nach einer erneuten Serverbereitstellung nicht mehr verfügbar sind.

React verfügt über ein Standardmuster für eine reibungslose Verarbeitung dieser Ladearten. Fehler: Verwendung einer Fehlergrenze. Wie in der Dokumentation beschrieben, kann jede React-Komponente als Fehlergrenze dienen, wenn sie entweder (oder der Lebenszyklusmethoden static getDerivedStateFromError() oder componentDidCatch().

Sie können Ihre Suspense zusammenfassen, um Lazy Loading-Fehler zu erkennen und zu beheben. Komponente mit einer übergeordneten Komponente, die als Fehlergrenze dient. Im Inneren der render()-Methode der Fehlergrenze können Sie die untergeordneten Elemente unverändert rendern, wenn keine Fehlermeldung angezeigt wird, oder geben Sie eine benutzerdefinierte Fehlermeldung aus, wenn ein Fehler auftritt:

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));

const renderLoader = () => <p>Loading</p>;

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {hasError: false};
  }

  static getDerivedStateFromError(error) {
    return {hasError: true};
  }

  render() {
    if (this.state.hasError) {
      return <p>Loading failed! Please reload.</p>;
    }

    return this.props.children;
  }
}

const DetailsComponent = () => (
  <ErrorBoundary>
    <Suspense fallback={renderLoader()}>
      <AvatarComponent />
      <InfoComponent />
      <MoreInfoComponent />
    </Suspense>
  </ErrorBoundary>
)

Fazit

Wenn Sie sich nicht sicher sind, wo Sie die Codeaufteilung auf Ihre React anwenden sollen führen Sie die folgenden Schritte aus:

  1. Beginnen Sie auf Routenebene. Routen sind die einfachste Möglichkeit, Punkte die aufgeteilt werden kann. Die React-Dokumente zeigen, wie Suspense zusammen mit react-router
  2. Identifizieren Sie alle großen Komponenten auf einer Seite Ihrer Website, die nur auf bestimmte Nutzerinteraktionen (z. B. das Klicken auf eine Schaltfläche) Diese werden aufgeteilt reduzieren die JavaScript-Nutzlasten.
  3. Erwägen Sie, alle anderen Bereiche aufzuteilen, die nicht sichtbar sind und für die Nutzer.