Front-End-Leistung 2021: Die Umgebung definieren

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Machen wir 2021 … schnell! Eine jährliche Front-End-Performance-Checkliste mit allem, was Sie wissen müssen, um heute schnelle Erfahrungen im Web zu erstellen, von Metriken über Tools bis hin zu Front-End-Techniken. Aktualisiert seit 2016.

Inhaltsverzeichnis

  1. Vorbereitung: Planung und Metriken
  2. Realistische Ziele setzen
  3. Die Umgebung definieren
  4. Asset-Optimierungen
  5. Build-Optimierungen
  6. Lieferoptimierungen
  7. Netzwerk, HTTP/2, HTTP/3
  8. Testen und Überwachen
  9. Schnelle Gewinne
  10. Alles auf einer Seite
  11. Checkliste herunterladen (PDF, Apple Pages, MS Word)
  12. Abonnieren Sie unseren E-Mail-Newsletter, um die nächsten Anleitungen nicht zu verpassen.

Die Umgebung definieren

  1. Wählen Sie Ihre Build-Tools aus und richten Sie sie ein.
    Achte heutzutage nicht zu sehr auf das, was angeblich cool ist. Halten Sie sich zum Erstellen an Ihre Umgebung, sei es Grunt, Gulp, Webpack, Parcel oder eine Kombination von Tools. Solange Sie die gewünschten Ergebnisse erzielen und keine Probleme haben, Ihren Build-Prozess aufrechtzuerhalten, geht es Ihnen gut.

    Unter den Build-Tools gewinnt Rollup immer mehr an Zugkraft, ebenso wie Snowpack, aber Webpack scheint das etablierteste zu sein, mit buchstäblich Hunderten von Plugins, die verfügbar sind, um die Größe Ihrer Builds zu optimieren. Achten Sie auf die Webpack-Roadmap 2021.

    Eine der bemerkenswertesten Strategien, die kürzlich erschienen sind, ist Granular Chunking mit Webpack in Next.js und Gatsby, um doppelten Code zu minimieren. Standardmäßig können Module, die nicht an jedem Einstiegspunkt gemeinsam genutzt werden, für Routen angefordert werden, die ihn nicht verwenden. Dies führt zu einem Overhead, da mehr Code als nötig heruntergeladen wird. Mit dem granularen Chunking in Next.js können wir eine serverseitige Build-Manifestdatei verwenden , um zu bestimmen, welche ausgegebenen Chunks von verschiedenen Einstiegspunkten verwendet werden.

    Um doppelten Code in Webpack-Projekten zu reduzieren, können wir granulares Chunking verwenden, das standardmäßig in Next.js und Gatsby aktiviert ist
    Um doppelten Code in Webpack-Projekten zu reduzieren, können wir granulares Chunking verwenden, das standardmäßig in Next.js und Gatsby aktiviert ist. Bildnachweis: Addy Osmani. (Große Vorschau)

    Mit SplitChunksPlugin werden abhängig von einer Reihe von Bedingungen mehrere Split-Chunks erstellt, um zu verhindern, dass duplizierter Code über mehrere Routen abgerufen wird. Dies verbessert die Seitenladezeit und das Caching während der Navigation. Ausgeliefert in Next.js 9.2 und in Gatsby v2.20.7.

    Der Einstieg in Webpack kann jedoch schwierig sein. Wenn Sie also in Webpack eintauchen möchten, gibt es einige großartige Ressourcen:

    • Die Webpack-Dokumentation ist – offensichtlich – ein guter Ausgangspunkt, ebenso wie Webpack – The Confusing Bits von Raja Rao und An Annotated Webpack Config von Andrew Welch.
    • Sean Larkin hat einen kostenlosen Kurs zu Webpack: The Core Concepts und Jeffrey Way hat einen fantastischen kostenlosen Kurs zu Webpack für alle veröffentlicht. Beide sind großartige Einführungen, um in Webpack einzutauchen.
    • Webpack Fundamentals ist ein sehr umfassender 4-stündiger Kurs mit Sean Larkin, veröffentlicht von FrontendMasters.
    • Webpack-Beispiele enthält Hunderte von gebrauchsfertigen Webpack-Konfigurationen, kategorisiert nach Thema und Zweck. Bonus: Es gibt auch einen Webpack-Konfigurationskonfigurator, der eine grundlegende Konfigurationsdatei generiert.
    • awesome-webpack ist eine kuratierte Liste nützlicher Webpack-Ressourcen, Bibliotheken und Tools, einschließlich Artikeln, Videos, Kursen, Büchern und Beispielen für Angular-, React- und Framework-unabhängige Projekte.
    • Der Weg zu schnellen Produktions-Asset-Builds mit Webpack ist Etsys Fallstudie darüber, wie das Team von der Verwendung eines RequireJS-basierten JavaScript-Build-Systems zur Verwendung von Webpack wechselte und wie es seine Builds optimierte und dabei über 13.200 Assets in durchschnittlich 4 Minuten verwaltete.
    • Webpack-Leistungstipps ist ein Goldminen-Thread von Ivan Akulov, der viele leistungsorientierte Tipps enthält, darunter auch solche, die sich speziell auf Webpack konzentrieren.
    • awesome-webpack-perf ist ein Goldminen-GitHub-Repo mit nützlichen Webpack-Tools und Plugins für die Leistung. Auch gepflegt von Ivan Akulov.
Eine Visualisierung von Etsys Weg zu schnellen Produktionsaufbauten mit Webpack
Etsys Reise zu schnellen Produktions-Builds mit Webpack (über Addy Osmani) (Große Vorschau)
  1. Verwenden Sie standardmäßig die progressive Verbesserung.
    Dennoch ist es nach all diesen Jahren eine sichere Sache, die progressive Verbesserung als Leitprinzip Ihrer Front-End-Architektur und -Bereitstellung beizubehalten. Entwerfen und erstellen Sie zuerst das Kernerlebnis und verbessern Sie dann das Erlebnis mit erweiterten Funktionen für leistungsfähige Browser, um belastbare Erlebnisse zu schaffen. Wenn Ihre Website auf einem langsamen Computer mit einem schlechten Bildschirm in einem schlechten Browser in einem suboptimalen Netzwerk schnell läuft, dann wird sie nur auf einem schnellen Computer mit einem guten Browser in einem anständigen Netzwerk schneller laufen.

    Tatsächlich scheinen wir mit dem adaptiven Modulserving die progressive Verbesserung auf eine andere Ebene zu heben, „leichte“ Kernerlebnisse für Low-End-Geräte bereitzustellen und mit ausgefeilteren Funktionen für High-End-Geräte zu verbessern. Die progressive Verbesserung wird wahrscheinlich in absehbarer Zeit nicht verschwinden.

  2. Wählen Sie eine starke Leistungsbaseline.
    Bei so vielen Unbekannten, die sich auf das Laden auswirken – das Netzwerk, thermische Drosselung, Cache-Eviction, Skripte von Drittanbietern, Parser-Blockierungsmuster, Festplatten-E/A, IPC-Latenz, installierte Erweiterungen, Antivirensoftware und Firewalls, Hintergrund-CPU-Aufgaben, Hardware- und Speichereinschränkungen, Unterschiede beim L2/L3-Caching, RTTS – JavaScript hat die höchsten Kosten der Erfahrung, neben Webfonts, die standardmäßig das Rendern blockieren, und Bildern, die oft zu viel Speicher verbrauchen. Da sich die Leistungsengpässe vom Server zum Client verlagern, müssen wir als Entwickler all diese Unbekannten viel detaillierter berücksichtigen.

    Mit einem Budget von 170 KB, das bereits den kritischen Pfad HTML/CSS/JavaScript, Router, Zustandsverwaltung, Dienstprogramme, Framework und die Anwendungslogik enthält, müssen wir die Netzwerkübertragungskosten, die Parsing-/Kompilierungszeit und die Laufzeitkosten gründlich untersuchen des Rahmens unserer Wahl. Glücklicherweise haben wir in den letzten Jahren eine enorme Verbesserung gesehen, wie schnell Browser Skripte parsen und kompilieren können. Die Ausführung von JavaScript ist jedoch immer noch der Hauptengpass, daher kann es von großer Bedeutung sein, auf die Skriptausführungszeit und das Netzwerk zu achten.

    Tim Kadlec hat eine fantastische Recherche zur Leistungsfähigkeit moderner Frameworks durchgeführt und diese in dem Artikel „JavaScript-Frameworks haben ihren Preis“ zusammengefasst. Wir sprechen oft über die Auswirkungen eigenständiger Frameworks, aber wie Tim anmerkt, ist es in der Praxis nicht ungewöhnlich, mehrere Frameworks zu verwenden . Vielleicht eine ältere Version von jQuery, die langsam auf ein modernes Framework migriert wird, zusammen mit einigen Legacy-Anwendungen, die eine ältere Version von Angular verwenden. Daher ist es sinnvoller, die kumulativen Kosten von JavaScript-Bytes und CPU-Ausführungszeit zu untersuchen, die Benutzererfahrungen selbst auf High-End-Geräten leicht kaum nutzbar machen können.

    Im Allgemeinen priorisieren moderne Frameworks weniger leistungsstarke Geräte nicht , sodass sich die Erfahrungen auf einem Telefon und auf dem Desktop in Bezug auf die Leistung oft dramatisch unterscheiden. Untersuchungen zufolge verbringen Websites mit React oder Angular mehr Zeit auf der CPU als andere (was natürlich nicht unbedingt heißt, dass React auf der CPU teurer ist als Vue.js).

    Laut Tim ist eines offensichtlich: „Wenn Sie ein Framework zum Erstellen Ihrer Website verwenden, gehen Sie einen Kompromiss in Bezug auf die anfängliche Leistung ein – selbst in den besten Szenarien.“

Die Kosten für Frameworks, JavaScript-CPU-Zeit: SPA-Sites schneiden schlecht ab
Kosten für Frameworks, JavaScript tschüss: SPA-Sites schneiden (noch) schlecht ab
Scripting-bezogene CPU-Zeit für Mobilgeräte und JavaScript-Bytes für Desktop-Geräte. Im Allgemeinen verbringen Websites mit React oder Angular mehr Zeit mit der CPU als andere. Aber es hängt davon ab, wie Sie die Website erstellen. Recherche von Tim Kadlec. (Große Vorschau)
  1. Bewerten Sie Frameworks und Abhängigkeiten.
    Nun braucht nicht jedes Projekt ein Framework und nicht jede Seite einer Single-Page-Anwendung muss ein Framework laden. Im Fall von Netflix „reduzierte das Entfernen von React, mehreren Bibliotheken und dem entsprechenden App-Code von der Client-Seite die Gesamtmenge an JavaScript um über 200 KB, was zu einer über 50-prozentigen Reduzierung der Time-to-Interactivity von Netflix für die abgemeldete Homepage führte ." Das Team nutzte dann die Zeit, die Benutzer auf der Zielseite verbrachten, um React für nachfolgende Seiten vorab abzurufen, auf denen Benutzer wahrscheinlich landen würden (lesen Sie weiter für Details).

    Was also, wenn Sie ein vorhandenes Framework auf kritischen Seiten vollständig entfernen? Mit Gatsby können Sie gatsby-plugin-no-javascript überprüfen, das alle von Gatsby erstellten JavaScript-Dateien aus den statischen HTML-Dateien entfernt. Auf Vercel können Sie auch das Deaktivieren von Laufzeit-JavaScript in der Produktion für bestimmte Seiten zulassen (experimentell).

    Sobald ein Framework ausgewählt ist, bleiben wir mindestens ein paar Jahre dabei. Wenn wir also eines verwenden müssen, müssen wir sicherstellen, dass unsere Wahl fundiert und wohlüberlegt ist – und das gilt insbesondere für wichtige Leistungsmetriken, die wir verwenden Wert darauf legen.

    Die Daten zeigen, dass Frameworks standardmäßig ziemlich teuer sind: 58,6 % der React-Seiten liefern mehr als 1 MB JavaScript, und 36 % der Vue.js-Seitenladevorgänge haben einen First Contentful Paint von <1,5 s. Laut einer Studie von Ankur Sethi „ wird Ihre React-Anwendung auf einem durchschnittlichen Telefon in Indien nie schneller als etwa 1,1 Sekunden laden , egal wie stark Sie sie optimieren. Ihre Angular-App benötigt immer mindestens 2,7 Sekunden zum Hochfahren Benutzer Ihrer Vue-App müssen mindestens 1 Sekunde warten, bevor sie sie verwenden können." Möglicherweise zielen Sie ohnehin nicht auf Indien als Ihren Hauptmarkt ab, aber Benutzer, die mit suboptimalen Netzwerkbedingungen auf Ihre Website zugreifen, werden eine vergleichbare Erfahrung machen.

    Natürlich ist es möglich, SPAs schnell zu machen, aber sie sind nicht sofort einsatzbereit, also müssen wir den Zeit- und Arbeitsaufwand berücksichtigen, der erforderlich ist, um sie schnell zu machen und zu halten . Es wird wahrscheinlich einfacher sein, wenn Sie sich frühzeitig für geringe Basisleistungskosten entscheiden.

    Wie wählen wir also einen Rahmen aus ? Es ist eine gute Idee, zumindest die Gesamtkosten für Größe + anfängliche Ausführungszeiten zu berücksichtigen, bevor Sie sich für eine Option entscheiden. leichte Optionen wie Preact, Inferno, Vue, Svelte, Alpine oder Polymer können die Arbeit gut erledigen. Die Größe Ihrer Baseline definiert die Einschränkungen für den Code Ihrer Anwendung.

    Wie von Seb Markbage angemerkt, besteht eine gute Möglichkeit, die Anlaufkosten für Frameworks zu messen, darin, zuerst eine Ansicht zu rendern, sie dann zu löschen und dann erneut zu rendern, da dies Aufschluss darüber gibt, wie das Framework skaliert. Das erste Rendern neigt dazu, einen Haufen faul kompilierten Codes aufzuwärmen, von dem ein größerer Baum profitieren kann, wenn er skaliert. Das zweite Rendering ist im Grunde eine Emulation dessen, wie sich die Wiederverwendung von Code auf einer Seite auf die Leistungsmerkmale auswirkt, wenn die Seite an Komplexität zunimmt.

    Sie könnten so weit gehen, Ihre Kandidaten (oder jede JavaScript-Bibliothek im Allgemeinen) auf dem 12-Punkte-Bewertungssystem von Sacha Greif zu bewerten, indem Sie Funktionen, Zugänglichkeit, Stabilität, Leistung, Paket-Ökosystem , Community, Lernkurve, Dokumentation, Werkzeuge und Erfolgsbilanz untersuchen , Team, Kompatibilität, Sicherheit zum Beispiel.

    Perf Track verfolgt die Framework-Leistung im großen Maßstab
    Perf Track verfolgt die Framework-Leistung im großen Maßstab. (Große Vorschau)

    Sie können sich auch auf Daten verlassen, die über einen längeren Zeitraum im Web gesammelt wurden. Beispielsweise verfolgt Perf Track die Framework-Leistung in großem Maßstab und zeigt ursprungsaggregierte Core Web Vitals -Ergebnisse für Websites, die in Angular, React, Vue, Polymer, Preact, Ember, Svelte und AMP erstellt wurden. Sie können sogar Websites angeben und vergleichen, die mit Gatsby, Next.js oder Create React App erstellt wurden, sowie Websites, die mit Nuxt.js (Vue) oder Sapper (Svelte) erstellt wurden.

    Ein guter Ausgangspunkt ist die Auswahl eines guten Standardstapels für Ihre Anwendung. Gatsby (React), Next.js (React), Vuepress (Vue), Preact CLI und PWA Starter Kit bieten vernünftige Standardwerte für schnelles Laden auf durchschnittlicher mobiler Hardware. Werfen Sie auch einen Blick auf die web.dev Framework-spezifischen Performance-Anleitungen für React und Angular ( Danke, Phillip! ).

    Und vielleicht könnten Sie einen etwas erfrischenderen Ansatz zum Erstellen von Single-Page-Anwendungen insgesamt wählen – Turbolinks, eine 15-KB-JavaScript-Bibliothek, die HTML anstelle von JSON zum Rendern von Ansichten verwendet. Wenn Sie also einem Link folgen, ruft Turbolinks automatisch die Seite ab, tauscht ihren <body> aus und fügt ihren <head> zusammen, ohne dass die Kosten für das Laden einer vollständigen Seite anfallen. Sie können schnelle Details und die vollständige Dokumentation über den Stack (Hotwire) überprüfen.

Ein histogrammartiges Diagramm, das die Rechenleistung der meistverkauften Telefone zeigt
CPU- und Rechenleistung der meistverkauften Telefone (Bildnachweis: Addy Osmani) (Große Vorschau)
  1. Clientseitiges Rendering oder serverseitiges Rendering? Beide!
    Das ist ein ziemlich hitziges Gespräch. Der ultimative Ansatz wäre, eine Art progressives Booten einzurichten: Verwenden Sie serverseitiges Rendering, um ein schnelles First Contentful Paint zu erhalten, aber fügen Sie auch etwas minimal notwendiges JavaScript hinzu, um die Zeit bis zur Interaktion nahe am First Contentful Paint zu halten. Wenn JavaScript zu spät nach dem FCP kommt, sperrt der Browser den Haupt-Thread, während spät entdecktes JavaScript analysiert, kompiliert und ausgeführt wird, wodurch die Interaktivität der Website oder Anwendung Handschellen erhält.

    Um dies zu vermeiden, unterteilen Sie die Ausführung von Funktionen immer in separate, asynchrone Aufgaben und verwenden Sie nach Möglichkeit requestIdleCallback . Erwägen Sie das verzögerte Laden von Teilen der Benutzeroberfläche mithilfe der dynamischen import() -Unterstützung von WebPack, um die Kosten für das Laden, Analysieren und Kompilieren zu vermeiden, bis die Benutzer sie wirklich brauchen ( danke Addy! ).

    Wie oben erwähnt, sagt uns Time to Interactive (TTI) die Zeit zwischen Navigation und Interaktivität. Im Detail wird die Metrik definiert, indem das erste Fünf-Sekunden-Fenster nach dem Rendern des anfänglichen Inhalts betrachtet wird, in dem keine JavaScript-Aufgaben länger als 50 ms dauern ( Long Tasks ). Wenn eine Aufgabe über 50 ms auftritt, beginnt die Suche nach einem Fünf-Sekunden-Fenster von vorne. Infolgedessen geht der Browser zunächst davon aus, dass er Interactive erreicht hat, nur um zu Frozen zu wechseln, nur um schließlich wieder zu Interactive zu wechseln.

    Sobald wir Interactive erreicht haben, können wir dann – entweder bei Bedarf oder wenn es die Zeit erlaubt – unwesentliche Teile der App booten. Wie Paul Lewis feststellte, haben Frameworks leider kein einfaches Prioritätskonzept, das Entwicklern offengelegt werden kann, und daher ist progressives Booten mit den meisten Bibliotheken und Frameworks nicht einfach zu implementieren.

    Trotzdem kommen wir ans Ziel. Heutzutage gibt es ein paar Möglichkeiten, die wir untersuchen können, und Houssein Djirdeh und Jason Miller bieten einen hervorragenden Überblick über diese Optionen in ihrem Vortrag über Rendering im Web und Jasons und Addys Artikel über moderne Front-End-Architekturen. Die folgende Übersicht basiert auf ihrer herausragenden Arbeit.

    • Vollständiges serverseitiges Rendern (SSR)
      Bei klassischem SSR wie WordPress werden alle Anfragen komplett auf dem Server abgewickelt. Der angeforderte Inhalt wird als fertige HTML-Seite zurückgegeben und kann sofort von Browsern gerendert werden. Daher können SSR-Apps beispielsweise die DOM-APIs nicht wirklich nutzen. Die Lücke zwischen First Contentful Paint und Time to Interactive ist normalerweise gering, und die Seite kann sofort gerendert werden, während HTML an den Browser gestreamt wird.

      Dadurch werden zusätzliche Roundtrips für das Abrufen von Daten und das Templating auf dem Client vermieden, da dies verarbeitet wird, bevor der Browser eine Antwort erhält. Am Ende haben wir jedoch eine längere Server-Denkzeit und folglich eine längere Zeit bis zum ersten Byte, und wir nutzen nicht die reaktionsschnellen und reichhaltigen Funktionen moderner Anwendungen.

    • Statisches Rendering
      Wir erstellen das Produkt als Einzelseitenanwendung, aber alle Seiten werden in statischem HTML mit minimalem JavaScript als Build-Schritt vorgerendert. Das bedeutet, dass wir beim statischen Rendering vorab individuelle HTML-Dateien für jede mögliche URL produzieren, was sich nicht viele Anwendungen leisten können. Da der HTML-Code für eine Seite jedoch nicht spontan generiert werden muss, können wir eine konstant schnelle Time To First Byte erreichen. So können wir schnell eine Zielseite anzeigen und dann ein SPA-Framework für nachfolgende Seiten vorab abrufen. Netflix hat diesen Ansatz übernommen und das Laden und die Time-to-Interactive um 50 % reduziert.

    • Serverseitiges Rendering mit (Re)Hydration (Universal Rendering, SSR + CSR)
      Wir können versuchen, das Beste aus beiden Welten zu nutzen – den SSR- und den CSR-Ansatz. Mit Hydratation im Mix enthält die vom Server zurückgegebene HTML-Seite auch ein Skript, das eine vollwertige clientseitige Anwendung lädt. Idealerweise erreicht man schnell ein First Contentful Paint (wie SSR) und setzt dann das Rendern mit (Re-)Hydration fort. Leider ist das selten der Fall. Häufiger sieht die Seite fertig aus, kann aber nicht auf Benutzereingaben reagieren, was zu wütenden Klicks und Abbrüchen führt.

      Mit React können wir das ReactDOMServer -Modul auf einem Node-Server wie Express verwenden und dann die Methode renderToString , um die Komponenten der obersten Ebene als statische HTML-Zeichenfolge zu rendern.

      Mit Vue.js können wir den vue-server-renderer verwenden, um eine Vue-Instanz mit renderToString in HTML zu rendern. In Angular können wir @nguniversal verwenden, um Client-Anfragen in vollständig vom Server gerenderte HTML-Seiten umzuwandeln. Ein vollständig vom Server gerendertes Erlebnis kann auch mit Next.js (React) oder Nuxt.js (Vue) erreicht werden.

      Der Ansatz hat seine Schattenseiten. Infolgedessen gewinnen wir die volle Flexibilität von clientseitigen Apps und bieten gleichzeitig ein schnelleres serverseitiges Rendering, aber am Ende haben wir auch eine längere Lücke zwischen First Contentful Paint und Time To Interactive und eine längere First Input Delay. Die Rehydrierung ist sehr teuer, und normalerweise reicht diese Strategie allein nicht aus, da sie die Time To Interactive stark verzögert.

    • Streaming serverseitiges Rendering mit progressiver Hydration (SSR + CSR)
      Um die Lücke zwischen Time To Interactive und First Contentful Paint zu minimieren, rendern wir mehrere Anfragen gleichzeitig und senden Inhalte in Blöcken, sobald sie generiert werden. Wir müssen also nicht auf die vollständige HTML-Zeichenfolge warten, bevor wir Inhalte an den Browser senden, und verbessern somit die Zeit bis zum ersten Byte.

      In React können wir anstelle von renderToString() renderToNodeStream() verwenden, um die Antwort weiterzuleiten und den HTML-Code in Blöcken zu senden. In Vue können wir renderToStream() verwenden, das geleitet und gestreamt werden kann. Mit React Suspense verwenden wir möglicherweise auch asynchrones Rendering für diesen Zweck.

      Auf der Client-Seite booten wir nicht die gesamte Anwendung auf einmal, sondern nach und nach Komponenten . Abschnitte der Anwendungen werden zunächst in eigenständige Skripte mit Code-Splitting zerlegt und dann schrittweise (in der Reihenfolge unserer Prioritäten) hydriert. Tatsächlich können wir kritische Komponenten zuerst hydratisieren, während der Rest später hydratisiert werden könnte. Die Rolle von clientseitigem und serverseitigem Rendering kann dann pro Komponente unterschiedlich definiert werden. Wir können dann auch die Hydratation einiger Komponenten verschieben, bis sie sichtbar werden oder für die Benutzerinteraktion benötigt werden oder wenn der Browser inaktiv ist.

      Für Vue hat Markus Oberlehner einen Leitfaden zur Reduzierung der Zeit bis zur Interaktion von SSR-Apps mithilfe von Hydration bei Benutzerinteraktion sowie vue-lazy-hydratation, einem Early-Stage-Plugin, das die Komponentenhydratation bei Sichtbarkeit oder spezifischer Benutzerinteraktion ermöglicht, veröffentlicht. Das Angular-Team arbeitet mit Ivy Universal an progressiver Flüssigkeitszufuhr. Sie können auch eine teilweise Hydration mit Preact und Next.js implementieren.

    • Trisomorphes Rendering
      Wenn Servicemitarbeiter vorhanden sind, können wir Streaming-Server-Rendering für anfängliche/Nicht-JS-Navigationen verwenden und dann den Servicemitarbeiter das Rendern von HTML für Navigationen übernehmen lassen, nachdem es installiert wurde. In diesem Fall rendert der Servicemitarbeiter Inhalte vorab und aktiviert SPA-Navigationen zum Rendern neuer Ansichten in derselben Sitzung. Funktioniert gut, wenn Sie den gleichen Templating- und Routing-Code zwischen dem Server, der Client-Seite und dem Servicemitarbeiter teilen können.

    Eine Illustration, die zeigt, wie trisomorphes Rendering an drei Stellen funktioniert, z. B. DOM-Rendering, Service-Worker-Pre-Rendering und serverseitiges Rendering
    Trisomorphes Rendering mit dem gleichen Code-Rendering an 3 beliebigen Stellen: auf dem Server, im DOM oder in einem Service-Worker. (Bildquelle: Google Developers) (Große Vorschau)
    • CSR mit Prerendering
      Prerendering ähnelt serverseitigem Rendering, aber anstatt Seiten auf dem Server dynamisch zu rendern, rendern wir die Anwendung zur Erstellungszeit in statisches HTML. Während statische Seiten ohne viel clientseitiges JavaScript vollständig interaktiv sind, funktioniert das Vorab-Rendering anders . Grundsätzlich erfasst es den Anfangszustand einer clientseitigen Anwendung als statisches HTML zur Erstellungszeit, während beim Vorab-Rendering die Anwendung auf dem Client gestartet werden muss, damit die Seiten interaktiv sind.

      Mit Next.js können wir den statischen HTML-Export verwenden, indem wir eine App vorab in statisches HTML rendern. In Gatsby verwendet ein Open-Source-Generator für statische Sites, der React verwendet, während des Builds die renderToStaticMarkup Methode anstelle der renderToString Methode, wobei der Haupt-JS-Chunk vorab geladen und zukünftige Routen vorab abgerufen werden, ohne DOM-Attribute, die für einfache statische Seiten nicht benötigt werden.

      Für Vue können wir Vuepress verwenden, um dasselbe Ziel zu erreichen. Sie können den Prerender-Loader auch mit Webpack verwenden. Navi bietet auch statisches Rendering.

      Das Ergebnis ist eine bessere „Time to First Byte“ und „First Contentful Paint“, und wir verringern die Lücke zwischen „Time To Interactive“ und „First Contentful Paint“. Wir können den Ansatz nicht verwenden, wenn erwartet wird, dass sich der Inhalt stark ändert. Außerdem müssen alle URLs im Voraus bekannt sein, um alle Seiten zu generieren. Einige Komponenten werden möglicherweise mithilfe von Prerendering gerendert, aber wenn wir etwas Dynamisches benötigen, müssen wir uns darauf verlassen, dass die App den Inhalt abruft.

    • Vollständiges clientseitiges Rendering (CSR)
      Die gesamte Logik, das Rendering und das Booten erfolgen auf dem Client. Das Ergebnis ist normalerweise eine große Lücke zwischen Time To Interactive und First Contentful Paint. Infolgedessen fühlen sich Anwendungen oft träge an, da die gesamte App auf dem Client gestartet werden muss, um etwas zu rendern.

      Da JavaScript Leistungseinbußen mit sich bringt, da die Menge an JavaScript mit einer Anwendung wächst, ist ein aggressives Code-Splitting und Zurückstellen von JavaScript absolut notwendig, um die Auswirkungen von JavaScript zu zähmen. Für solche Fälle ist ein serverseitiges Rendering normalerweise ein besserer Ansatz, falls nicht viel Interaktivität erforderlich ist. Wenn dies nicht möglich ist, sollten Sie das App Shell-Modell verwenden.

      Im Allgemeinen ist SSR schneller als CSR. Dennoch ist es eine ziemlich häufige Implementierung für viele Apps da draußen.

    Also clientseitig oder serverseitig? Im Allgemeinen ist es eine gute Idee, die Verwendung vollständig clientseitiger Frameworks auf Seiten zu beschränken , die sie unbedingt benötigen. Für fortgeschrittene Anwendungen ist es auch keine gute Idee, sich allein auf serverseitiges Rendern zu verlassen. Sowohl Server- als auch Client-Rendering sind eine Katastrophe, wenn sie schlecht gemacht werden.

    Unabhängig davon, ob Sie zu CSR oder SSR neigen, stellen Sie sicher, dass Sie wichtige Pixel so schnell wie möglich rendern, und minimieren Sie die Lücke zwischen diesem Rendering und Time To Interactive. Erwägen Sie das Vorab-Rendering, wenn sich Ihre Seiten nicht stark ändern, und verschieben Sie das Booten von Frameworks, wenn Sie können. Streamen Sie HTML in Blöcken mit serverseitigem Rendering und implementieren Sie progressive Hydration für clientseitiges Rendering – und hydratisieren Sie bei Sichtbarkeit, Interaktion oder während der Leerlaufzeit, um das Beste aus beiden Welten zu erhalten.

Eine Tabelle, in der Optionen für clientseitiges und serverseitiges Rendering verglichen werden
Das Spektrum der Optionen für clientseitiges versus serverseitiges Rendern. Sehen Sie sich auch den Vortrag von Jason und Houssein auf der Google I/O zu den Auswirkungen der Anwendungsarchitektur auf die Leistung an. (Bildquelle: Jason Miller) (Große Vorschau)
Ein Beispiel für die Website von AirBnB, das links ohne progressive Flüssigkeitszufuhr und rechts mit progressiver Flüssigkeitszufuhr gezeigt wird
AirBnB hat mit progressiver Flüssigkeitszufuhr experimentiert; Sie verschieben nicht benötigte Komponenten, laden bei Benutzerinteraktion (Scrollen) oder während der Leerlaufzeit und Tests zeigen, dass dies TTI verbessern kann. (Große Vorschau)
  1. Wie viel können wir statisch servieren?
    Unabhängig davon, ob Sie an einer großen Anwendung oder einer kleinen Website arbeiten, sollten Sie überlegen, welche Inhalte statisch von einem CDN (dh JAM Stack) bereitgestellt werden könnten, anstatt dynamisch im laufenden Betrieb generiert zu werden. Selbst wenn Sie Tausende von Produkten und Hunderte von Filtern mit zahlreichen Personalisierungsoptionen haben, möchten Sie Ihre wichtigen Zielseiten möglicherweise dennoch statisch bereitstellen und diese Seiten vom Rahmen Ihrer Wahl entkoppeln.

    Es gibt viele Static-Site-Generatoren und die von ihnen generierten Seiten sind oft sehr schnell. Je mehr Inhalte wir im Voraus erstellen können, anstatt Seitenaufrufe auf einem Server oder Client zum Zeitpunkt der Anfrage zu generieren, desto bessere Leistung erzielen wir.

    In Building Partially Hydrated, Progressively Enhanced Static Websites zeigt Markus Oberlehner, wie man Websites mit einem Static-Site-Generator und einem SPA erstellt und dabei eine progressive Verbesserung und eine minimale JavaScript-Bundle-Größe erreicht. Markus verwendet Eleventy und Preact als seine Tools und zeigt, wie man die Tools einrichtet, partielle Hydration, Lazy Hydration, Client-Eintragsdatei hinzufügt, Babel für Preact konfiguriert und Preact mit Rollup bündelt – von Anfang bis Ende.

    Da JAMStack heutzutage auf großen Websites verwendet wird, tauchte ein neuer Leistungsaspekt auf: die Build-Zeit . Tatsächlich kann das Erstellen von Tausenden von Seiten mit jeder neuen Bereitstellung Minuten dauern, daher ist es vielversprechend, inkrementelle Builds in Gatsby zu sehen, die die Build-Zeiten um das 60-fache verbessern, mit einer Integration in beliebte CMS-Lösungen wie WordPress, Contentful, Drupal, Netlify CMS und andere.

    Ein Flussdiagramm, das Benutzer 1 oben links und Benutzer 2 unten links zeigt und den Prozess der inkrementellen Statuserneuerung zeigt
    Inkrementelle statische Regenerierung mit Next.js. (Bildnachweis: Prisma.io) (Große Vorschau)

    Außerdem kündigte Next.js eine vorzeitige und inkrementelle statische Generierung an, die es uns ermöglicht, neue statische Seiten zur Laufzeit hinzuzufügen und vorhandene Seiten zu aktualisieren, nachdem sie bereits erstellt wurden, indem sie im Hintergrund neu gerendert werden, wenn der Datenverkehr eingeht .

    Benötigen Sie einen noch leichteren Ansatz? In seinem Vortrag über Eleventy, Alpine und Tailwind: Toward a Lightweight Jamstack erklärt Nicola Goutay die Unterschiede zwischen CSR, SSR und allem dazwischen und zeigt, wie man einen leichteren Ansatz verwendet – zusammen mit einem GitHub-Repo, das den Ansatz zeigt in der Praxis.

  2. Erwägen Sie die Verwendung von PRPL-Muster und App-Shell-Architektur.
    Unterschiedliche Frameworks haben unterschiedliche Auswirkungen auf die Leistung und erfordern unterschiedliche Optimierungsstrategien, daher müssen Sie alle Grundlagen des Frameworks, auf das Sie sich verlassen, klar verstehen. Sehen Sie sich beim Erstellen einer Web-App das PRPL-Muster und die Anwendungs-Shell-Architektur an. Die Idee ist ganz einfach: Pushen Sie den minimalen Code, der benötigt wird, um interaktiv zu werden, damit die anfängliche Route schnell gerendert wird, verwenden Sie dann Service Worker zum Caching und Pre-Caching von Ressourcen und laden Sie dann asynchron die Routen, die Sie benötigen.
PRPL-Muster in der Anwendungs-Shell-Architektur
PRPL steht für Pushing Critical Resource, Rendering Initial Route, Pre-Caching Residual Routes und Lazy-Loading Residual Routes On Demand.
Anwendungs-Shell-Architektur
Eine Anwendungsshell ist das minimale HTML, CSS und JavaScript, das eine Benutzeroberfläche antreibt.
  1. Haben Sie die Leistung Ihrer APIs optimiert?
    APIs sind Kommunikationskanäle für eine Anwendung, um Daten über Endpunkte für interne Anwendungen und Anwendungen von Drittanbietern verfügbar zu machen . Beim Entwerfen und Erstellen einer API benötigen wir ein angemessenes Protokoll, um die Kommunikation zwischen dem Server und Anfragen von Drittanbietern zu ermöglichen. Representational State Transfer ( REST ) ist eine etablierte, logische Wahl: Es definiert eine Reihe von Einschränkungen, denen Entwickler folgen, um Inhalte auf performante, zuverlässige und skalierbare Weise zugänglich zu machen. Webdienste, die den REST-Einschränkungen entsprechen, werden als RESTful-Webdienste bezeichnet.

    Wie bei den guten alten HTTP-Anforderungen wird beim Abrufen von Daten von einer API jede Verzögerung in der Serverantwort an den Endbenutzer weitergegeben, wodurch das Rendern verzögert wird. Wenn eine Ressource Daten von einer API abrufen möchte, muss sie die Daten vom entsprechenden Endpunkt anfordern. Eine Komponente, die Daten aus mehreren Ressourcen rendert, z. B. ein Artikel mit Kommentaren und Autorenfotos in jedem Kommentar, benötigt möglicherweise mehrere Roundtrips zum Server, um alle Daten abzurufen, bevor sie gerendert werden können. Darüber hinaus ist die über REST zurückgegebene Datenmenge oft größer als zum Rendern dieser Komponente erforderlich ist.

    Wenn viele Ressourcen Daten von einer API benötigen, kann die API zu einem Leistungsengpass werden. GraphQL bietet eine leistungsfähige Lösung für diese Probleme. An sich ist GraphQL eine Abfragesprache für Ihre API und eine serverseitige Laufzeit zum Ausführen von Abfragen unter Verwendung eines Typsystems, das Sie für Ihre Daten definieren. Im Gegensatz zu REST kann GraphQL alle Daten in einer einzigen Anfrage abrufen, und die Antwort wird genau das sein, was erforderlich ist, ohne dass Daten zu viel oder zu wenig abgerufen werden, wie dies normalerweise bei REST der Fall ist.

    Da GraphQL außerdem Schemas verwendet (Metadaten, die angeben, wie die Daten strukturiert sind), kann es Daten bereits in der bevorzugten Struktur organisieren, sodass wir beispielsweise mit GraphQL den JavaScript-Code entfernen könnten, der für den Umgang mit der Zustandsverwaltung und der Produktion verwendet wird einen saubereren Anwendungscode, der auf dem Client schneller ausgeführt wird.

    Wenn Sie mit GraphQL beginnen möchten oder auf Leistungsprobleme stoßen, könnten diese Artikel sehr hilfreich sein:

    • A GraphQL Primer: Why We Need A New Art of API von Eric Baer,
    • A GraphQL Primer: The Evolution Of API Design von Eric Baer,
    • Entwerfen eines GraphQL-Servers für optimale Leistung von Leonardo Losoviz,
    • GraphQL-Leistung erklärt von Wojciech Trocki.
Zwei Beispiele für mobile Schnittstellen für Nachrichten bei Verwendung von Redux/REST (links) und Apollo/GraphQL (rechts)
Ein Unterschied zwischen REST und GraphQL, illustriert durch ein Gespräch zwischen Redux + REST auf der linken Seite, ein Apollo + GraphQL auf der rechten Seite. (Bildquelle: Hacker Noon) (Große Vorschau)
  1. Werden Sie AMP oder Instant Articles verwenden?
    Abhängig von den Prioritäten und der Strategie Ihrer Organisation möchten Sie vielleicht die Verwendung von Googles AMP oder Facebooks Instant Articles oder Apples Apple News in Betracht ziehen. Sie können auch ohne sie eine gute Leistung erzielen, aber AMP bietet mit einem kostenlosen Content Delivery Network (CDN) ein solides Leistungsgerüst, während Instant Articles Ihre Sichtbarkeit und Leistung auf Facebook steigern.

    Der scheinbar offensichtliche Vorteil dieser Technologien für Benutzer ist die garantierte Leistung , sodass sie manchmal sogar AMP-/Apple News/Instant Pages-Links gegenüber „normalen“ und möglicherweise aufgeblähten Seiten bevorzugen. Bei inhaltsintensiven Websites, die mit vielen Inhalten von Drittanbietern zu tun haben, könnten diese Optionen möglicherweise dazu beitragen, die Renderzeiten drastisch zu verkürzen.

    Es sei denn, sie tun es nicht. Laut Tim Kadlec zum Beispiel „sind AMP-Dokumente tendenziell schneller als ihre Gegenstücke, aber sie bedeuten nicht unbedingt, dass eine Seite performant ist.

    Ein Vorteil für den Website-Betreiber liegt auf der Hand: Auffindbarkeit dieser Formate auf ihren jeweiligen Plattformen und erhöhte Sichtbarkeit in Suchmaschinen.

    Naja, zumindest war das früher so. Da AMP für Top Stories nicht mehr erforderlich ist, wechseln Publisher möglicherweise von AMP zu einem traditionellen Stack ( danke, Barry! ).

    Dennoch könnten Sie auch progressive Web-AMPs erstellen, indem Sie AMPs als Datenquelle für Ihre PWA wiederverwenden. Nachteil? Offensichtlich versetzt eine Präsenz in einem ummauerten Garten Entwickler in die Lage, eine separate Version ihres Inhalts zu erstellen und zu pflegen, und im Falle von Instant Articles und Apple News ohne tatsächliche URLs (danke Addy, Jeremy!) .

  2. Wählen Sie Ihr CDN mit Bedacht aus.
    Wie oben erwähnt, können Sie abhängig davon, wie viele dynamische Daten Sie haben, möglicherweise einen Teil des Inhalts an einen Generator für statische Websites „auslagern“, ihn an ein CDN senden und von dort eine statische Version bereitstellen, wodurch Anfragen an die vermieden werden Server. Tatsächlich sind einige dieser Generatoren tatsächlich Website-Compiler mit vielen automatisierten Optimierungen, die sofort einsatzbereit sind. Wenn Compiler im Laufe der Zeit Optimierungen hinzufügen, wird die kompilierte Ausgabe mit der Zeit kleiner und schneller.

    Beachten Sie, dass CDNs auch dynamische Inhalte bereitstellen (und auslagern) können. Es ist also nicht notwendig, Ihr CDN auf statische Assets zu beschränken. Überprüfen Sie noch einmal, ob Ihr CDN Komprimierung und Konvertierung durchführt (z. B. Bildoptimierung und Größenänderung am Rand), ob es Unterstützung für Server-Worker, A/B-Tests sowie Edge-Side-Includes bietet, die statische und dynamische Teile von Seiten zusammenstellen am Rand des CDN (d. h. dem Server, der dem Benutzer am nächsten ist) und andere Aufgaben. Überprüfen Sie auch, ob Ihr CDN HTTP über QUIC (HTTP/3) unterstützt.

    Katie Hempenius hat einen fantastischen Leitfaden für CDNs geschrieben, der Einblicke in die Auswahl eines guten CDNs, seine Feinabstimmung und all die kleinen Dinge gibt, die bei der Bewertung eines CDNs zu beachten sind. Im Allgemeinen ist es eine gute Idee, Inhalte so aggressiv wie möglich zwischenzuspeichern und CDN-Leistungsfunktionen wie Brotli, TLS 1.3, HTTP/2 und HTTP/3 zu aktivieren.

    Hinweis : Basierend auf Untersuchungen von Patrick Meenan und Andy Davies wird die HTTP/2-Priorisierung auf vielen CDNs effektiv gebrochen, seien Sie also vorsichtig bei der Auswahl eines CDN. Patrick hat mehr Details in seinem Vortrag über die HTTP/2-Priorisierung ( Danke, Barry! ).

    CDNPerf-Vorschau von CDN-Namen und Abfragegeschwindigkeit in ms
    CDNPerf misst die Abfragegeschwindigkeit für CDNs, indem täglich 300 Millionen Tests gesammelt und analysiert werden. (Große Vorschau)

    Bei der Auswahl eines CDN können Sie diese Vergleichsseiten mit einer detaillierten Übersicht ihrer Funktionen nutzen:

    • CDN-Vergleich, eine CDN-Vergleichsmatrix für Cloudfront, Aazure, KeyCDN, Fastly, Verizon, Stackpach, Akamai und viele andere.
    • CDN Perf misst die Abfragegeschwindigkeit für CDNs, indem täglich 300 Millionen Tests gesammelt und analysiert werden, wobei alle Ergebnisse auf RUM-Daten von Benutzern auf der ganzen Welt basieren. Sehen Sie sich auch den DNS-Leistungsvergleich und den Cloud-Leistungsvergleich an.
    • CDN Planet Guides bietet einen Überblick über CDNs zu bestimmten Themen wie Serve Stale, Purge, Origin Shield, Prefetch und Compression.
    • Web Almanac: CDN Adoption and Usage bietet Einblicke in die wichtigsten CDN-Anbieter, ihre RTT- und TLS-Verwaltung, TLS-Aushandlungszeit, HTTP/2-Einführung und andere. (Leider sind die Daten nur von 2019).

Inhaltsverzeichnis

  1. Vorbereitung: Planung und Metriken
  2. Realistische Ziele setzen
  3. Die Umgebung definieren
  4. Asset-Optimierungen
  5. Build-Optimierungen
  6. Lieferoptimierungen
  7. Netzwerk, HTTP/2, HTTP/3
  8. Testen und Überwachen
  9. Schnelle Gewinne
  10. Alles auf einer Seite
  11. Checkliste herunterladen (PDF, Apple Pages, MS Word)
  12. Abonnieren Sie unseren E-Mail-Newsletter, um die nächsten Anleitungen nicht zu verpassen.