Nicht verwendeten Code entfernen

Verbessern Sie in diesem Codelab die Leistung der folgenden Anwendung. Entfernen Sie dazu alle nicht verwendeten und nicht benötigten Abhängigkeiten.

App – Screenshot

Messen

Es empfiehlt sich immer, zuerst die Leistung einer Website zu messen, bevor Sie Optimierungen vornehmen.

  • Um die Website als Vorschau anzusehen, wählen Sie App ansehen und dann Vollbild Vollbild aus.

Probier es aus und klicke auf dein Lieblingskätzchen. In dieser Anwendung wird die Echtzeitdatenbank von Firebase verwendet. Deshalb wird der Wert in Echtzeit aktualisiert und mit jeder anderen Person synchronisiert, die die Anwendung verwendet. 🐈

  1. Drücken Sie Strg + Umschalttaste + J (oder Befehlstaste + Option + J auf dem Mac), um die Entwicklertools zu öffnen.
  2. Klicken Sie auf den Tab Netzwerk.
  3. Klicken Sie das Kästchen Cache deaktivieren an.
  4. Aktualisieren Sie die App.

Ursprüngliche Paketgröße: 992 KB

Zum Laden dieser einfachen Anwendung werden fast 1 MB an JavaScript-Code versendet!

Sieh dir die Projektwarnungen in den Entwicklertools an.

  • Klicken Sie auf den Tab Console.
  • Achten Sie darauf, dass Warnings im Drop-down-Menü „Ebenen“ neben der Eingabe Filter aktiviert ist.

Filter für Warnungen

  • Wirf einen Blick auf die angezeigte Warnung.

Konsolenwarnung

Firebase, eine der Bibliotheken, die in dieser Anwendung verwendet werden, ist ein guter Samariter. Sie warnt Entwickler, nicht das gesamte Paket, sondern nur die verwendeten Komponenten zu importieren. Mit anderen Worten: Es gibt nicht verwendete Bibliotheken, die in dieser Anwendung entfernt werden können, damit sie schneller geladen wird.

Es gibt auch Fälle, in denen eine bestimmte Bibliothek verwendet wird, es kann jedoch auch eine einfachere Alternative geben. Das Konzept des Entfernens nicht benötigter Bibliotheken wird später in dieser Anleitung behandelt.

Bundle wird analysiert

In der Anwendung gibt es zwei Hauptabhängigkeiten:

  • Firebase: eine Plattform, die eine Reihe nützlicher Dienste für iOS-, Android- oder Webanwendungen bietet. Hier wird die Realtime Database verwendet, um die Informationen für jedes Kätzchen in Echtzeit zu speichern und zu synchronisieren.
  • Moment.js: Eine Dienstprogrammbibliothek, die die Verarbeitung von Datumsangaben in JavaScript vereinfacht. Das Geburtsdatum jedes Kätzchens wird in der Firebase-Datenbank gespeichert. moment wird verwendet, um sein Alter in Wochen zu berechnen.

Wie können schon zwei Abhängigkeiten zu einer Bundle-Größe von fast 1 MB beitragen? Nun, einer der Gründe ist, dass jede Abhängigkeit ihrerseits eigene Abhängigkeiten haben kann. Es gibt also viel mehr als nur zwei, wenn jede Tiefe/jede Zweig des Abhängigkeitsbaums berücksichtigt wird. Eine Anwendung kann relativ schnell schnell groß werden, wenn viele Abhängigkeiten enthalten sind.

Analysieren Sie den Bundler, um eine bessere Vorstellung davon zu bekommen, was passiert. Dafür gibt es eine Reihe verschiedener von der Community entwickelter Tools, z. B. webpack-bundle-analyzer.

Das Paket für dieses Tool ist bereits als devDependency in der App enthalten.

"devDependencies": {
  //...
  "webpack-bundle-analyzer": "^2.13.1"
},

Das bedeutet, dass sie direkt in der Webpack-Konfigurationsdatei verwendet werden kann. Importieren Sie es am Anfang von webpack.config.js:

const path = require("path");

//...
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;

Fügen Sie es jetzt als Plug-in ganz am Ende der Datei im Array plugins hinzu:

module.exports = {
  //...
  plugins: [
    //...
    new BundleAnalyzerPlugin()
  ]
};

Wenn die Anwendung neu geladen wird, sollten Sie eine Visualisierung des gesamten Bundles anstelle der App selbst sehen.

Webpack Bundle Analyzer

Nicht so süß wie ein paar Kätzchen 🔔, aber trotzdem unglaublich hilfreich. Wenn Sie den Mauszeiger auf eines der Pakete bewegen, wird seine Größe auf drei verschiedene Arten dargestellt:

Statistikgröße Größe vor Komprimierung oder Komprimierung.
Geparste Größe Größe des tatsächlichen Pakets innerhalb des Bundles, nachdem es kompiliert wurde. Version 4 des Webpacks, die in dieser Anwendung verwendet wird, reduziert die kompilierten Dateien automatisch. Daher ist dies kleiner als die Statistikgröße.
Mit gzip komprimierte Größe Größe des Pakets, nachdem es mit gzip-Codierung komprimiert wurde. Dieses Thema wird in einem separaten Leitfaden behandelt.

Mit dem Webpack-bundle-Analyzer-Tool kannst du nicht verwendete oder nicht benötigte Pakete, die einen großen Teil des Pakets ausmachen, einfacher identifizieren.

Nicht verwendete Pakete entfernen

Die Visualisierung zeigt, dass das Paket firebase viel mehr als nur eine Datenbank enthält. Sie umfasst zusätzliche Pakete, darunter:

  • firestore
  • auth
  • storage
  • messaging
  • functions

Dies sind alles hervorragende Dienste von Firebase (weitere Informationen dazu finden Sie in der Dokumentation), aber keiner wird in der Anwendung verwendet, daher gibt es keinen Grund, sie alle zu importieren.

Machen Sie die Änderungen in webpack.config.js rückgängig, um die Anwendung wieder zu sehen:

  • Entfernen Sie BundleAnalyzerPlugin aus der Liste der Plug-ins:
plugins: [
  //...
  new BundleAnalyzerPlugin()
];
  • Entfernen Sie jetzt den nicht verwendeten Import am Anfang der Datei:
const path = require("path");

//...
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

Die Anwendung sollte jetzt wieder normal geladen werden. Ändern Sie src/index.js, um die Firebase-Importe zu aktualisieren.

import firebase from 'firebase';
import firebase from 'firebase/app';
import 'firebase/database';

Wenn die App jetzt neu geladen wird, wird die Warnung in den Entwicklertools nicht mehr angezeigt. Wenn du in den Entwicklertools den Bereich Netzwerk öffnest, siehst du auch eine erleichterte Reduzierung der Bundle-Größe:

Paketgröße auf 480 KB reduziert

Es wurde mehr als die Hälfte der Paketgröße entfernt. Firebase bietet viele verschiedene Dienste und bietet Entwicklern die Möglichkeit, nur die tatsächlich benötigten Dienste einzubeziehen. In dieser Anwendung wurde nur firebase/database zum Speichern und Synchronisieren aller Daten verwendet. Der firebase/app-Import, mit dem die API-Oberfläche für jeden der verschiedenen Dienste eingerichtet wird, ist immer erforderlich.

Viele andere beliebte Bibliotheken wie lodash ermöglichen es Entwicklern, unterschiedliche Teile ihrer Pakete selektiv zu importieren. Wenn Sie den Bibliotheksimport in einer Anwendung so aktualisieren, dass nur das, was verwendet wird, berücksichtigt wird, kann dies zu erheblichen Leistungsverbesserungen führen.

Obwohl die Größe des Pakets um einiges reduziert wurde, gibt es noch mehr zu tun! 😈

Nicht benötigte Pakete entfernen

Im Gegensatz zu Firebase ist das Importieren von Teilen der moment-Bibliothek nicht so einfach möglich. Möglicherweise ist es aber auch vollständig entfernt.

Das Geburtsdatum jedes niedlichen Kätzchens wird im Unix-Format (in Millisekunden) in der Firebase-Datenbank gespeichert.

Geburtsdaten im Unix-Format gespeichert

Dies ist ein Zeitstempel für ein bestimmtes Datum und eine bestimmte Uhrzeit, dargestellt durch die Anzahl der Millisekunden, die seit dem 1. Januar 1970 um 00:00 Uhr (UTC) vergangen sind. Wenn das aktuelle Datum und die aktuelle Uhrzeit im gleichen Format berechnet werden können, lässt sich wahrscheinlich eine kleine Funktion erstellen, um das Alter jedes Kätzchens in Wochen zu ermitteln.

Versuchen Sie wie immer, nicht zu kopieren und einzufügen, während Sie die nachfolgenden Schritte ausführen. Entfernen Sie zuerst moment aus den Importen in src/index.js.

import firebase from 'firebase/app';
import 'firebase/database';
import * as moment from 'moment';

Es gibt einen Firebase-Event-Listener, der Wertänderungen in unserer Datenbank verarbeitet:

favoritesRef.on("value", (snapshot) => { ... })

Fügen Sie darüber eine kleine Funktion hinzu, um die Anzahl der Wochen ab einem bestimmten Datum zu berechnen:

const ageInWeeks = birthDate => {
  const WEEK_IN_MILLISECONDS = 1000 * 60 * 60 * 24 * 7;
  const diff = Math.abs((new Date).getTime() - birthDate);
  return Math.floor(diff / WEEK_IN_MILLISECONDS);
}

In dieser Funktion wird die Differenz in Millisekunden zwischen dem aktuellen Datum und der aktuellen Uhrzeit (new Date).getTime() und dem Geburtsdatum (das Argument birthDate, bereits in Millisekunden) berechnet und durch die Anzahl der Millisekunden in einer einzelnen Woche dividiert.

Schließlich können alle Instanzen von moment im Event-Listener entfernt werden, indem stattdessen diese Funktion genutzt wird:

favoritesRef.on("value", (snapshot) => {
  const { kitties, favorites, names, birthDates } = snapshot.val();
  favoritesScores = favorites;

  kittiesList.innerHTML = kitties.map((kittiePic, index) => {
    const birthday = moment(birthDates[index]);

    return `
      <li>
        <img src=${kittiePic} onclick="favKittie(${index})">
        <div class="extra">
          <div class="details">
            <p class="name">${names[index]}</p>
            <p class="age">${moment().diff(birthday, 'weeks')} weeks old</p>
            <p class="age">${ageInWeeks(birthDates[index])} weeks old</p>
          </div>
          <p class="score">${favorites[index]} ❤</p>
        </div>
      </li>
    `})
});

Aktualisieren Sie nun die Anwendung und sehen Sie sich das Steuerfeld Netzwerk noch einmal an.

Paketgröße auf 225 KB reduziert

Die Größe unseres Sets hat sich wieder um mehr als die Hälfte reduziert.

Fazit

Mit diesem Codelab sollten Sie ein gutes Verständnis dafür haben, wie ein bestimmtes Bundle analysiert wird und warum es so nützlich sein kann, nicht verwendete oder nicht benötigte Pakete zu entfernen. Bevor Sie mit dieser Technik beginnen, eine Anwendung zu optimieren, sollten Sie wissen, dass dies bei größeren Anwendungen deutlich komplexer sein kann.

Versuchen Sie in Bezug auf das Entfernen nicht verwendeter Bibliotheken herauszufinden, welche Teile eines Bundles verwendet werden und welche nicht. Bei einem mysteriös wirkenden Paket, das so aussieht, als ob es nirgendwo verwendet wird, gehen Sie einen Schritt zurück und prüfen, welche Abhängigkeiten der obersten Ebene es benötigen. Versuchen Sie, einen Weg zu finden, sie voneinander zu entkoppeln.

Das Entfernen nicht benötigter Bibliotheken kann etwas komplizierter sein. Es ist wichtig, eng mit Ihrem Team zusammenzuarbeiten und zu prüfen, ob es Potenzial gibt, Teile der Codebasis zu vereinfachen. Das Entfernen von moment in dieser Anwendung mag so aussehen, als wäre es jedes Mal richtig, aber was wäre, wenn Zeitzonen und verschiedene Sprachen bearbeitet werden müssten? Oder was wäre, wenn es kompliziertere Datumsmanipulationen gäbe? Beim Bearbeiten und Parsen von Datums- und Uhrzeitangaben kann es sehr knifflig werden. Dies wird in Bibliotheken wie moment und date-fns erheblich vereinfacht.

In jedem Fall müssen Sie Abstriche machen und abwägen, ob sich die Komplexität und der Aufwand der Einführung einer benutzerdefinierten Lösung überhaupt lohnen. Die Nutzung einer Drittanbieterbibliothek ist damit nicht notwendig.