Freigeben über


Dynamisches Laden von Paketen in SharePoint Framework

Beim Erstellen von SharePoint-Framework-Komponenten ist es üblich, auf Drittanbieterbibliotheken, z. B. Office UI Fabric React für Benutzeroberflächensteuerungen oder auf Moment.js für die Verarbeitung von Zeit zu verweisen. Jede dieser Bibliotheken trägt zur Größe der gebündelten JavaScript-Datei für die Komponente bei. In diesem Beispiel fügt Moment.js dem resultierenden Paket ca. 250 KB hinzu!

Hinweis

Bei einem JavaScript-Bündel handelt es sich um eine JavaScript-Datei, die eine oder mehrere JavaScript-Dateien oder Stylesheets kombiniert. Wenn Sie eine SPFx-Projektmappe packen, werden standardmäßig der gesamte Code und die Bibliotheken, die Sie in Ihr Projekt importieren, in einer *.js-Datei gebündelt. Das Aufteilen eines Bündels ist der Vorgang, mehrere *.js-Dateien anstelle einer datei zu generieren, damit sie einzeln geladen werden können.

In Abhängigkeit von der Komponente können diese Drittanbieterbibliotheken in allen Teilen des Komponentenlebenszyklus verwendet werden. Vielleicht werden sie nur im Bearbeitungsmodus oder im Eigenschaftenbereich verwendet, oder vielleicht werden sie einmal benötigt, wenn ein Benutzer auf einen Link oder eine Schaltfläche in der Komponente klickt.

Wenn die SPFx-Komponente eine Single-Page-Webanwendung (SPA) ist, ist das Optimieren der Größe vielleicht nicht wichtig, aber wenn die Komponente ein Webpart ist, das zu einer Seite hinzugefügt wird oder sogar mehrere Male auf einer Seite verwendet wird, z. B. ein Such-Webpart, so ist das Reduzieren der geladenen und ausgeführten Skriptmenge auf einer Seite für die Ladezeit der Seite entscheidend. Dies kann sich erheblich auf die mobile Erfahrungen auswirken.

Um die Geschwindigkeit einer SPFx-Komponente beim Laden einer Seite zu verbessern, kann das Paket in mehrere JavaScript-Teile aufgeteilt werden; diese separat gebündelten Pakete können bei Bedarf dynamisch geladen werden.

Teilen Sie mehrere Webparts auf, die einzeln geladen werden sollen

Ein SPFx-Projekt mit mehreren Webparts oder Erweiterungen enthält die Datei ./config/config.json ähnlich der folgenden:

{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
  "version": "2.0",
  "bundles": {
    "my-spfx": {
      "components": [
        {
          "entrypoint": "./lib/webparts/part1/part1.js",
          "manifest": "./src/webparts/part1/part1.manifest.json"
        },
        {
          "entrypoint": "./lib/webparts/part2/part2.js",
          "manifest": "./src/webparts/part2/part2.manifest.json"
        }
      ]
    }
  },
  "externals": {},
  "localizedResources": {}
}

In der obigen Konfiguration werden beide Webparts in dasselbe JavaScript-Paket eingeschlossen. Dies bedeutet, wenn ein Benutzer einen der Webparts zu einer Seite hinzufügt, werden beide geladen. Bei Szenarien, in denen sich beide Webparts gleichzeitig auf derselben Seite befinden, ist dies in Ordnung, da es die Ladezeit beim Herunterladen einer Datei anstelle von zwei Dateien reduziert.

Wenn die Webparts jedoch separat verwendet werden, ist es besser, sie in zwei Dateien aufzuteilen, um zu reduzieren, was die Seite herunterladen muss, um nur eine von ihnen auszuführen.

Dies kann erreicht werden, indem Sie config/config.json so ändern, dass jedes Webpart als separate JavaScript-Datei gebündelt wird:

{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
  "version": "2.0",
  "bundles": {
    "my-spfx-1": {
      "components": [
        {
          "entrypoint": "./lib/webparts/part1/part1.js",
          "manifest": "./src/webparts/part1/part1.manifest.json"
        }
      ]
    },
    "my-spfx-2": {
      "components": [
        {
          "entrypoint": "./lib/webparts/part2/part2.js",
          "manifest": "./src/webparts/part2/part2.manifest.json"
        }
      ]
    }
  },
  "externals": {},
  "localizedResources": {}
}

Ihr Paket analysieren

Um einen Überblick darüber zu erhalten, wo Sie beginnen und optimieren sollten, lesen Sie den Artikel Optimieren SharePoint-Framework Builds für die Produktion, in dem veranschaulicht wird, wie Sie eine visuelle Übersicht darüber erhalten können, welcher Teil Ihres Codes oder der Drittanbieterbibliothek Platz in Ihrem Bündel beansprucht.

Dynamisches Laden von Drittanbieterkomponenten

Wenn eine SharePoint-Framework-Lösung gepackt wird, verwendet der Build-Toolchain Webpack, um das/die Paket(e) zu generieren. Eines der Features von Webpack ist das dynamische Importieren von Teilen einer Anwendung. Sie können dies in SharePoint-Framework-Projekten mit einer geringfügigen Codeumgestaltung implementieren.

Normaler Import

Im folgenden Code wird die "Moment.js"-Bibliothek mit dem JavaScript-Paket "Lösung" einbezogen. Dieser Code wird auf der Seite immer geladen, auch wenn die Methode GetTime() niemals aufgerufen wird.

import * as moment from moment

export default class MyClass {
  public GetTime(dateString:string){
    return moment(dateString).format("LL");
  }
}

Dynamischer Import

Im folgenden Code wird jedoch die "Moment.js"-Bibliothek asynchron geladen, wenn die GetTime()-Methode aufgerufen wird, wodurch die anfängliche Auslastung und die Ausführungszeit verringert wird. Beachten Sie den zusätzlichen webpackChuckName-Codekommentar

export default class MyClass {
  public async GetTime(dateString:string) {
    const moment = await import(
      /* webpackChunkName: 'my-moment' */
      'moment'
    );
    return moment(dateString).format("LL");
  }
}

Hinweis

Wenn Ihre config/tsconfig.json-Datei "module": "commonjs" und nicht "module": "esnext" aufweist, benötigen Sie die folgende Problemumgehung, damit die dynamische Bibliothek von dem Paket getrennt wird.

declare var System: any;

export default class MyClass {
  public async GetTime(dateString:string){
    const moment = await System.import(
      /* webpackChunkName: 'my-moment' */
      'moment'
    );
    return moment(dateString).format("LL");
  }
}

Überprüfen der Codeaufteilung und dynamischer Import

Um sicherzustellen, dass der dynamische Import stattfindet, öffnen Sie den Ordner ./dist nach der Ausführung gulp bundle-Aufgabe und suchen Sie nach der dynamisch geladenen Bibliothek als separate JavaScript-Datei. In der folgenden Abbildung ist die "Moment.js"-Bibliothek in eine eigene Datei aufgeteilt.

Mehrere Pakete

Nicht jede Datei oder Bibliothek sollte dynamisch importiert werden. Erwägen Sie stattdessen, wie Codeblöcke für bestimmte Szenarien oder Fähigkeiten zu einem einzigen Bündel zusammenzufassen.

Erstellen Sie z. B. eine **MyStuff.ts-Datei, die auf eine Reihe von Bibliotheken verweist, und laden Sie dann MyStuff dynamisch. In diesem Fall werden die Bibliotheken third-party und left-party in my-stuff.js gebündelt.

// MyStuff.ts

import { Something } from 'third-party;'
import * as Foo from 'left-party';

// Other file
await import(
  /* webpackChunkName: 'my-stuff' */
  './MyStuff'
);

Dynamisches Laden eines speziellen Eigenschaftenbereichs

Ein weiterer Anwendungsfall für diese Fähigkeit ist der dynamische Import von Code, der nur im Eigenschaftenbereich verwendet wird. In diesem Fall sollten Sie diesen Code nur in den Browser herunterladen, wenn der Eigenschaftenbereich des Webparts aktiviert ist.

Erstellen Sie in Ihrer Haupt-Webpartdatei eine Funktion mit dem Namen loadPropertyPaneResources(). Diese Funktion wird ausgeführt, bevor der Eigenschaftenbereich eines Webparts angezeigt wird. Dadurch wird das dynamische Laden von Ressourcen ermöglicht, die nur für den Eigenschaftenbereich erforderlich sind.

  1. Erstellen Sie eine neue Datei HelloWorldWebPartPropertyPaneStuff.ts
  2. Verschieben Sie dem gesamten Code im Zusammenhang mit dem Eigenschaftenbereich in diese Datei
  3. Erstellen Sie die folgende Methode in der Haupt-Webpartklasse
protected loadPropertyPaneResources(): Promise<void> {
  return import(
    /* webpackChunkName: 'HelloWorldWebPartPropertyPaneStuff' */
    './HelloWorldWebPartPropertyPaneStuff'
  ).then(component => {
    this._propertyPaneHelper = new component.HelloWorldWebPartPropertyPaneStuff(this);
  });
}

Zusammenfassung

Wenn Sie SPFx-Lösungen erstellen, die aus mehreren Komponenten bestehen, oder wenn Sie Bibliotheken von Drittanbietern verwenden, sollten Sie dynamische Importe in Betracht ziehen. Analysieren Sie zunächst die resultierende Paketgröße und verwenden Sie die auf dieser Seite beschriebenen Strategien, um den Code in mehrere Pakete aufzuteilen, von denen jedes nur bei Bedarf geladen wird. Dadurch wird die Zeit verringert, die ein Endbenutzer benötigt, um die Seite zu laden und auszuführen.