Website Performance Optimierung: Pagespeed

Front-End-Leistungs-Checkliste 2020
Nachfolgend finden Sie eine Übersicht über die Front-End-Performance-Probleme, die Sie möglicherweise berücksichtigen müssen, um schnelle und reibungslose Antwortzeiten zu gewährleisten.
____

Planung und Metriken

    • Etablieren Sie eine Leistungskultur.

      Solange es kein Buy-in der Unternehmen gibt, kann die Leistung nicht langfristig aufrechterhalten werden. Untersuchen Sie häufige Beschwerden, die beim Kundendienst eingehen, und finden Sie heraus, wie die Verbesserung der Leistung dazu beitragen kann, einige dieser Probleme zu lösen. Erstellen Sie eine auf das Unternehmen zugeschnittene Fallstudie mit echten Daten und Geschäftskennzahlen. Planen Sie eine Ladereihenfolge und Kompromisse während des Designprozesses.

    • Seien Sie 20 % schneller als Ihr schnellster Mitbewerber.

      Sammeln Sie Daten auf einem für Ihre Zielgruppe repräsentativen Gerät. Bevorzugen Sie reale Geräte gegenüber Simulationen. Wählen Sie ein Moto G4/G5 Plus, ein Samsung-Gerät der Mittelklasse (Galaxy A50, S8), ein gutes Gerät der Mittelklasse wie einen Nexus 5X, Xiaomi Mi A3 oder Xiaomi Redmi Note 7 und ein langsames Gerät wie Alcatel 1X oder Cubot X19. Alternativ können Sie mobile Erfahrungen auf dem Desktop emulieren, indem Sie auf einem gedrosselten Netzwerk (z.B. 300ms RTT, 1,6 Mbps unten, 0,8 Mbps oben) mit einer gedrosselten CPU (5× Verlangsamung) testen. Dann wechseln Sie zu regulärem 3G, langsamem 4G (z.B. 170ms RTT, 9 Mbps abwärts, 9 Mbps aufwärts) und Wi-Fi. Sammeln Sie Daten, erstellen Sie eine Tabellenkalkulation, rasieren Sie 20% ab und legen Sie Ihre Ziele (Leistungsbudgets) fest.

    • Wählen Sie die richtigen Metriken.

      Nicht jede Metrik ist gleich wichtig. Untersuchen Sie, welche Metriken am wichtigsten sind: Gewöhnlich hängt es davon ab, wie schnell Sie mit dem Rendern der wichtigsten Pixel beginnen können und wie schnell Sie auf Eingaben reagieren können. Priorisieren Sie das Laden von Seiten so, wie es von Ihren Kunden wahrgenommen wird. Die Zeit bis zur Interaktivität, die erste Eingabeverzögerung, die Renderingzeiten des Helden, der größte zufriedenstellende Farbauftrag, die Gesamtblockierungszeit, die kumulative Layoutverschiebung und der Geschwindigkeitsindex spielen normalerweise eine Rolle.

    • Richten Sie „saubere“ und „Kunden“-Profile für Tests ein.

      Schalten Sie Anti-Virus und Hintergrund-CPU-Aufgaben ab, entfernen Sie Bandbreitenübertragungen im Hintergrund und testen Sie mit einem sauberen Benutzerprofil ohne Browser-Erweiterungen, um verzerrte Ergebnisse zu vermeiden. Untersuchen Sie, welche Erweiterungen Ihre Kunden verwenden, und testen Sie auch mit einem speziellen „Kunden“-Profil.

    • Geben Sie die Checkliste an Ihre Kollegen weiter.

      Stellen Sie sicher, dass die Checkliste jedem Mitglied Ihres Teams bekannt ist. Jede Entscheidung hat Auswirkungen auf die Leistung, und es wäre für Ihr Projekt von großem Vorteil, die Verantwortung auf das gesamte Team zu verteilen. Ordnen Sie Designentscheidungen dem Leistungsbudget zu.

Realistische Ziele setzen

      • 100 Millisekunden Reaktionszeit, 60 Bilder pro Sekunde.

        Jedes Einzelbild der Animation sollte in weniger als 16 Millisekunden idealerweise 10 Millisekunden abgeschlossen sein, wodurch 60 Bilder pro Sekunde (1 Sekunde ÷ 60 = 16,6 Millisekunden) erreicht werden. Seien Sie optimistisch und nutzen Sie die ungenutzte Zeit weise. Für Punkte mit hohem Druck wie die Animation ist es am besten, nichts anderes zu tun, wo es möglich ist, und das absolute Minimum, wo es nicht möglich ist. Die geschätzte Input-Latenzzeit sollte unter 50 ms liegen. Nutzen Sie die Leerlaufzeit vernünftig mit dem Ansatz „Leerlauf bis zur Dringlichkeit“.

      • FID < 100ms, Time-To-Interactive < 5s bei 3G.

        Wenn man als Ausgangsbasis ein Android-Telefon im Wert von 200 USD auf einem langsamen 3G-Telefon, emuliert mit 400 ms RTT und 400 kbps Übertragungsgeschwindigkeit, nimmt man an, dass die Time-to-Interactive-Zeit < 5 s und für wiederholte Besuche unter 2-3 s liegt. Angestrebt wird ein größtmöglicher Contentful Paint von unter 1s und eine Minimierung der Gesamtblockierungszeit und der kumulativen Layoutverschiebung. Bemühen Sie sich, diese Werte so niedrig wie möglich zu halten.

      • Kritisches Budget für Dateigrößen < 170 KB Die ersten 14-16 KB des HTML-Dokuments sind der kritischste Teil der Nutzlast und der einzige Teil des Budgets, der im ersten Roundtrip geliefert werden kann. Um die oben genannten Ziele zu erreichen, sollten Sie sich an ein kritisches Dateigrößen-Budget von max. 170KB gzipped (0,7-0,8MB dekomprimiert. Stellen Sie sicher, dass sich Ihre Budgets je nach Netzwerkbedingungen und Hardwarebeschränkungen ändern.

Definieren der Umgebung

      • Wählen Sie Ihre Build-Tools aus und richten Sie sie ein.

        Achten Sie nicht so sehr darauf, was angeblich cool ist. Solange Sie schnell Ergebnisse erzielen und keine Probleme haben, Ihren Build-Prozess aufrechtzuerhalten, sind Sie gut unterwegs. Die einzige Ausnahme könnte Webpack sein, das viele nützliche Optimierungstechniken wie Code-Splitting bietet. Wenn es noch nicht in Gebrauch ist, sollten Sie sich im Detail mit Code-Splitting und Tree-shaking beschäftigen.

      • Verwenden Sie standardmäßig die progressive Verbesserung.

        Entwerfen und erstellen Sie zunächst das Kernerlebnis, und verbessern Sie dann das Erlebnis mit erweiterten Funktionen für fähige Browser, um ein belastbares Erlebnis zu schaffen. Wenn Ihre Website auf einem langsamen Rechner mit einem schlechten Bildschirm in einem schlechten Browser in einem suboptimalen Netzwerk schnell läuft, wird sie nur auf einem schnellen Rechner mit einem guten Browser in einem anständigen Netzwerk schneller laufen.

      • Wählen Sie eine starke Leistungsbasis.

        JavaScript hat die höchsten Kosten für die Erfahrung. Bei einem Budget von 170 KB, das bereits HTML/CSS/JavaScript für den kritischen Pfad, Router, Statusverwaltung, Dienstprogramme, Framework und die Anwendungslogik enthält, sollten Sie die Netzwerkübertragungskosten, die Parse-/Kompilierzeit und die Laufzeitkosten für das Framework unserer Wahl gründlich prüfen.

      • Bewerten Sie jedes Framework und jede Abhängigkeit.

        Nicht jedes Projekt benötigt ein Framework, nicht jede Seite einer SPA muss das Framework laden. Seien Sie bei Ihren Entscheidungen überlegt. Bewerten Sie JS von Drittanbietern, indem Sie Funktionen, Zugänglichkeit, Stabilität, Leistung, Paket-Ökosystem, Gemeinschaft, Lernkurve, Dokumentation, Werkzeuge, Erfolgsbilanz, Team, Kompatibilität und Sicherheit untersuchen. Gatsby (React), Vuepress (Vue) und Preact CLI bieten vernünftige Standardeinstellungen für das schnelle Laden out of the box auf durchschnittlicher mobiler Hardware.

      • Wählen Sie Ihre Kämpfe mit Bedacht: React, Vue, Angular, Ember und Co.

        Stellen Sie sicher, dass das Framework Ihrer Wahl serverseitiges Rendering bietet. Stellen Sie sicher, dass Sie die Bootzeiten im Server und Client-Rendering-Modus auf mobilen Geräten messen, bevor Sie sich für ein Framework entscheiden. Verstehen Sie die Schrauben und Muttern des Frameworks, auf das Sie sich verlassen werden. Informieren Sie sich über das PRPL-Muster und die Shell-Architektur der Anwendung.

      • Optimieren Sie die Leistung Ihrer APIs.

        Wenn viele Ressourcen Daten von einer API benötigen, kann die API zu einem Leistungsengpass werden. Erwägen Sie die Verwendung von GraphQL, einer Abfragesprache und einer serverseitigen Laufzeit zur Ausführung von Abfragen unter Verwendung eines von Ihnen für Ihre Daten definierten Typensystems. Im Gegensatz zu REST kann GraphQL alle Daten in einer einzigen Anfrage abrufen, ohne dass Daten über oder untermäßig abgerufen werden, wie es bei REST typischerweise geschieht.

      • Werden Sie AMP oder Instant Articles verwenden?

        Sie können auch ohne sie eine gute Leistung erzielen, aber AMP könnte mit einem kostenlosen CDN einen soliden Leistungsrahmen bieten, während Instant Articles Ihre Sichtbarkeit und Leistung auf Facebook steigern wird. Sie könnten auch progressive Web-AMPs erstellen.

      • Wählen Sie Ihr CDN mit Bedacht.

        Je nachdem, wie viele dynamische Daten Sie haben, können Sie möglicherweise einen Teil des Inhalts an einen statischen Website-Generator „auslagern“, ihn in ein CDN schieben und von dort aus eine statische Version bereitstellen und so Datenbankanforderungen (JAMStack) vermeiden. Vergewissern Sie sich, dass Ihr CDN Inhaltskomprimierung und -konvertierung (z.B. Bildoptimierung in Bezug auf Formate, Komprimierung und Größenänderung am Rand), Unterstützung für Serverarbeiter und Edge-Side-Includes für Sie durchführt.

Asset-Optimierungen

      • Verwenden Sie Brotli für die Komprimierung von reinem Text.

        Brotli, ein neues verlustfreies Datenformat, wird jetzt in allen modernen Browsern unterstützt. Es ist effektiver als Gzip und Deflate, komprimiert sehr langsam, dekomprimiert aber schnell. Statische Assets werden mit Brotli+Gzip auf der höchsten Stufe vorkomprimiert, (dynamisches) HTML wird mit Brotli auf Stufe 1-4 on the fly komprimiert. Prüfen Sie auch bei CDNs auf Brotli-Unterstützung. Stellen Sie sicher, dass der Server die Inhaltsaushandlung für Brotli oder gzip korrekt handhabt.

      • Verwenden Sie reaktionsfähige Bilder und WebP.

        Verwenden Sie, soweit möglich, responsive Bilder mit srcset, Größen und dem Element <picture>. Verwenden Sie das WebP-Format, indem Sie WebP-Bilder mit <picture> und einem JPEG-Fallback bereitstellen oder indem Sie die Inhaltsaushandlung verwenden (unter Verwendung von Accept-Headern). Hinweis: Mit WebP verringern Sie die Nutzlast, aber mit JPEG verbessern Sie die wahrgenommene Leistung, so dass die Benutzer ein tatsächliches Bild mit einem guten alten JPEG schneller sehen können, obwohl WebP-Bilder schneller durch das Netzwerk gelangen.

      • Sind Bilder richtig optimiert?

        Verwenden Sie mozJPEG für die JPEG-Komprimierung, SVGO für die SVG-Komprimierung, Pingo für PNGs oder Squoosh für alle. Um die Effizienz Ihres Response-Markups zu überprüfen, können Sie Imaging-Heap verwenden. Verwenden Sie für kritische Bilder progressive JPEGs und verwischen Sie unnötige Teile (durch Anwendung eines Gaußschen Weichzeichnungsfilters) und entfernen Sie den Kontrast (Sie können ihn mit CSS-Filtern erneut anwenden). Stellen Sie sicher, dass Breite und Höhe für alle Bilder definiert sind, fügen Sie eine automatische Bildkomprimierung zu Ihren Pull-Anforderungen hinzu und schauen Sie sich weniger kritische Bilder an, die zu langsam geladen werden.

      • Sind Videos richtig optimiert?

        Verwenden Sie anstelle von animierten GIFs entweder animiertes WebP (wobei GIF ein Fallback ist) oder inline HTML5-Videos in Schleifen. Stellen Sie sicher, dass Ihre MP4s mit einer Multipasskodierung verarbeitet, mit dem frei0r-Iirblur-Effekt (falls zutreffend) verwischt und Moov-Atom-Metadaten an den Anfang der Datei verschoben werden, während Ihr Server Byte-Serving akzeptiert. Seien Sie auf das AV1-Format vorbereitet, das gute Chancen hat, der ultimative Standard für Video im Web zu werden.

      • Sind Web-Schriftarten optimiert?

        Die Chancen stehen gut, dass die Web-Schriftarten, die Sie bereitstellen, Glyphen und zusätzliche Funktionen enthalten, die nicht wirklich genutzt werden. Unterteilen Sie die Schriftarten. Bevorzugen Sie WOFF2 und verwenden Sie WOFF als Ausweichlösung. Zeigen Sie den Inhalt in den Ersatzschriftarten sofort an, laden Sie die Schriftarten asynchron und wechseln Sie dann die Schriftarten in dieser Reihenfolge. Endgültige Lösung: zweistufiges Rendern, zunächst mit einem kleinen Supersubset, und der Rest der Familie wird später asynchron geladen. Laden Sie 1-2 Schriftarten jeder Familie vor. Vermeiden Sie den local()-Wert für Schriftartendeklarationen, sondern berücksichtigen Sie lokal installierte OS-Schriftarten. Vergessen Sie nicht, font-display: optional einzuschließen, und verwenden Sie Font Load Events für Gruppen-Neuzeichnungen. Verwenden Sie Web Font Reflow Count und Time To Real Kursiv-Metriken.

Build-Optimierungen

      • Setzen Sie Ihre Prioritäten richtig.

        Führen Sie eine Bestandsaufnahme all Ihrer Assets durch (JavaScript, Bilder, Schriften, Skripte von Drittanbietern, „teure“ Module auf der Seite), und gliedern Sie sie in Gruppen auf. Definieren Sie die grundlegende Kern-Erfahrung (vollständig zugängliche Kerninhalte für ältere Browser), die erweiterte Erfahrung (eine angereicherte, vollständige Erfahrung für fähige Browser) und die Extras (Assets, die nicht unbedingt benötigt werden und die sich faul laden lassen).

      • Verwendung nativer JavaScript-Module in der Produktion.

        Übertragen Sie die Kern-Erfahrung auf ältere Browser und eine verbesserte Erfahrung auf moderne Browser. Verwenden Sie ES2015+ <script type=“module“> zum Laden von JavaScript: Moderne Browser interpretieren das Skript als JavaScript-Modul und führen es wie erwartet aus, während ältere Browser es nicht erkennen und daher ignorieren würden. Rollup und Parcel unterstützen bereits Module als Ausgabeformat.

      • Die Ausführung von JavaScript ist teuer, also zähmen Sie es.

        Bei SPAs benötigen Sie möglicherweise einige Zeit, um die Anwendung zu initialisieren, bevor Sie die Seite rendern können. Suchen Sie nach Modulen und Techniken, um die anfängliche Renderzeit zu beschleunigen (sie kann auf mobilen Low-End-Geräten leicht um das 2 bis 5-fache höher sein).

      • Verwenden Sie Tree-shaking, Scope-Histing und Code-Splitting, um die Nutzlast zu reduzieren.

        Tree-shaking ist eine Möglichkeit, Ihren Build-Prozess zu bereinigen, indem Sie nur Code einbeziehen, der tatsächlich in der Produktion verwendet wird. Beim Code-Splitting wird Ihre Code-Basis in „Brocken“ aufgeteilt, die bei Bedarf geladen werden. Scope Hoisting erkennt, wo die Importverkettung abgeflacht und in eine Inline-Funktion umgewandelt werden kann, ohne den Code zu beeinträchtigen (z. B. über Webpack). Verwenden Sie einen vorzeitigen Compiler, um einen Teil des Client-seitigen Renderings auf den Server auszulagern. Definieren Sie Split-Punkte, indem Sie verfolgen, welche CSS/JS-Blöcke verwendet werden und welche nicht. Ziehen Sie auch Code-Splitting auf der Paketebene in Betracht.

      • Können Sie JavaScript in einen Web Worker oder eine WebAssembly auslagern?

        Wenn sich die Codebasis weiterentwickelt, werden Engpässe bei der UI-Leistung auftreten. Dies geschieht, weil DOM-Operationen neben Ihrem JS auf dem Hauptthread laufen. Ziehen Sie in Betracht, diese teuren Operationen in einen Hintergrundprozess zu verlagern, der auf einem anderen Thread mit Web-Workern läuft. Typischer Anwendungsfall: Prefetching von Daten und PWAs. Erwägen Sie, rechenintensive Aufgaben auf WebAssembly auszulagern, was am besten für rechenintensive Webanwendungen, wie z.B. Webspiele, funktioniert.

      • Servieren von Legacy-Code nur für ältere Browser (differential serving).

        Verwenden Sie babel-preset-env, um nur ES2015+-Funktionen zu übertragen, die von den modernen Browsern, auf die Sie abzielen, nicht unterstützt werden. Richten Sie dann zwei Builds ein, einen in ES6 und einen in ES5. Verwenden Sie für lodash babel-plugin-lodash, das nur Module lädt, die Sie in Ihrem Quellcode verwenden. Um Code-Duplizierung zu vermeiden, müssen Sie generische Lodash-Builds in die richtigen Module umwandeln. Verwenden Sie den Header <link rel=“modulepreload“>, um ein frühzeitiges (und hochprioritäres) Laden von Modulskripten einzuleiten.

      • Identifizieren und Neuschreiben von Legacy-Code mit inkrementeller Entkopplung.

        Überprüfen Sie Ihre Abhängigkeiten und schätzen Sie ein, wie viel Zeit für das Refactoring oder Neuschreiben von Legacy-Code benötigt würde, der in letzter Zeit Probleme verursacht hat. Richten Sie zunächst Metriken ein, die verfolgen, ob das Verhältnis der Aufrufe von Legacy-Code konstant bleibt oder abnimmt, nicht ansteigt. Halten Sie das Team öffentlich davon ab, die Bibliothek zu benutzen, und stellen Sie sicher, dass Ihre CI die Entwickler benachrichtigt, wenn sie bei Pull-Anfragen verwendet wird.

      • Identifizieren und entfernen Sie nicht verwendetes CSS/JavaScript.

        Durch die Abdeckung von CSS und JavaScript-Code in Chrome können Sie erfahren, welcher Code ausgeführt bzw. angewendet wurde und welcher nicht. Sobald Sie unbenutzten Code entdeckt haben, können Sie diese Module finden und mit import() faul laden. Wiederholen Sie dann das Abdeckungsprofil und bestätigen Sie, dass nun beim ersten Laden weniger Code ausgeliefert wird. Verwenden Sie Puppeteer, um Code-Abdeckung programmatisch zu sammeln.

      • Verringern Sie die Größe Ihrer JavaScript-Abhängigkeiten.

        Es besteht eine hohe Wahrscheinlichkeit, dass Sie vollständige JavaScript-Bibliotheken ausliefern, wenn Sie nur einen Bruchteil davon benötigen. Um diesen Overhead zu vermeiden, sollten Sie die Verwendung von Webpack-Libs-Optimierungen in Betracht ziehen, die während des Build-Prozesses nicht verwendete Methoden und Polyfills entfernen. Fügen Sie Bundle-Auditing in Ihren regulären Arbeitsablauf ein. Bundlephobie hilft bei der Ermittlung der Kosten für das Hinzufügen eines npm-Pakets zu Ihrem Bundle, Größenbeschränkung erweitert die grundlegende Überprüfung der Bundle-Größe um Details zur JavaScript-Ausführungszeit.

      • Verwenden Sie prädiktives Prefetching für JavaScript-Blöcke?

        Verwenden Sie Heuristiken, um zu entscheiden, wann JavaScript-Blöcke vorgeladen werden sollen. Guess.js ist ein Satz von Tools, die Google Analytics-Daten verwenden, um zu ermitteln, welche Seite ein Benutzer wahrscheinlich als Nächstes besuchen wird. Denken Sie auch an Quicklink, Instant.page und DNStradamus. Hinweis: Möglicherweise werden Sie den Browser dazu auffordern, nicht benötigte Daten zu verbrauchen und unerwünschte Seiten vorab abzurufen. Es ist daher ratsam, bei der Anzahl der vorab abgerufenen Seiten recht konservativ vorzugehen.

      • Optimieren Sie für Ihre JavaScript-Ziel-Engines.

        Nutzen Sie Skript-Streaming für monolithische Skripte, so dass sie auf einem separaten Hintergrund-Thread geparst werden können, sobald das Herunterladen beginnt. Hängen Sie sich auch in das Code-Caching von V8 ein, indem Sie die Bibliotheken von dem Code, der sie verwendet, trennen, oder umgekehrt. Ziehen Sie auch JIT-Optimierungsstrategien für Firefox’s Baseline Interpeter in Betracht.

      • Finden Sie einen Weg, Client-seitiges Rendering und Server-seitiges Rendering miteinander zu verbinden.

        Normalerweise besteht das Ziel darin, die optimale Balance zwischen client-seitigem und serverseitigem Rendering zu finden. Ziehen Sie ein Prerendering in Betracht, wenn sich Ihre Seiten nicht viel ändern, und verschieben Sie das Booten von Frameworks, wenn Sie können. Streamen Sie HTML in Brocken mit serverseitigem Rendering, und implementieren Sie eine progressive Hydratisierung für einzelne Komponenten mit client-seitigem Rendering und hydratisieren Sie bei Sichtbarkeit, Interaktion oder während Leerlaufzeiten, um das Beste aus beiden Welten zu erhalten. (Streaming Server-seitiges Rendering mit progressiver Hydratisierung).

      • Ziehen Sie Mikro-Optimierungen und progressives Booten in Betracht.

        Verwenden Sie Server-seitiges Rendering, um schnell eine erste sinnvolle Farbe zu erhalten, aber fügen Sie auch einige minimale JS ein, um die Zeit bis zur Interaktion nahe an der ersten sinnvollen Farbe zu halten. Booten Sie dann, entweder auf Anforderung oder wenn es die Zeit erlaubt, nicht-essentielle Teile der Anwendung. Unterteilen Sie die Ausführung von Funktionen immer in separate, asynchrone Aufgaben. Wenn möglich, verwenden Sie requestIdleCallback.

      • Immer Self-Hosting von Drittanbieter-Assets.

        Die Verwendung eines öffentlichen CDN führt nicht automatisch zu einer besseren Leistung. Selbst wenn zwei Sites auf genau dieselbe Ressourcen-URL eines Drittanbieters verweisen, wird der Code einmal pro Domäne heruntergeladen, und der Cache wird in diese Domäne „sandboxed“. Es ist wahrscheinlicher, dass die Ressourcen der ersten Partei im Cache bleiben als die Ressourcen Dritter. Self-Hosting ist zuverlässiger, sicherer und besser für die Leistung.

      • Beschränken Sie die Auswirkungen von Skripten Dritter.

        Zu oft endet ein einziges Skript eines Drittanbieters damit, dass es eine lange Reihe von Skripten aufruft. Erwägen Sie den Einsatz von Service-Mitarbeitern, indem Sie den Ressourcen-Download mit einem Timeout beschleunigen. Legen Sie eine Richtlinie zur Inhaltssicherheit (Content Security Policy, CSP) fest, um die Auswirkungen von Skripten Dritter einzuschränken, z.B. das Herunterladen von Audio oder Video zu verbieten. Betten Sie Skripte über Iframe ein, so dass Skripte keinen Zugriff auf das DOM haben. Sandkasten sie auch. Um Skripte einem Stresstest zu unterziehen, prüfen Sie die Bottom-up-Zusammenfassungen auf der Seite Leistungsprofil (DevTools).

      • Setzen Sie HTTP-Cache-Header richtig.

        Überprüfen Sie, ob die Gültigkeitsdauer, die Cache-Kontrolle, das maximale Alter und andere HTTP-Cache-Header richtig eingestellt sind. Im Allgemeinen sollten Ressourcen entweder für eine sehr kurze Zeit (wenn sie sich wahrscheinlich ändern) oder für unbestimmte Zeit (wenn sie statisch sind) im Cache gespeichert werden können. Cache-Kontrolle verwenden: unveränderlich, konzipiert für statische Ressourcen mit Fingerabdrücken, um eine Revalidierung zu vermeiden. Stellen Sie sicher, dass Sie keine unnötigen Header senden (wie x-powered-by, pragma, x-ua-kompatibel, verfällt). Verwenden Sie Null-RTT für wiederholte Ansichten, indem Sie stale-while-revalidate verwenden.

Zustell-Optimierungen

      • JavaScript asynchron laden.

        Als Entwickler müssen wir den Browser explizit darauf hinweisen, nicht zu warten und mit dem Rendern der Seite mit den Attributen defer und async in HTML zu beginnen. Wenn Sie sich über IE 9 und darunter keine großen Sorgen machen müssen, dann ziehen Sie den Defer dem Async vor. Mit defer führt der Browser keine Skripte aus, bis HTML geparst ist. Wenn Sie also JS nicht ausführen müssen, bevor Sie mit dem Rendern beginnen, ist es besser, defer zu verwenden.

      • Langsames Laden teurer Komponenten mit IntersectionObserver.

        Langsames Laden aller teuren Komponenten wie JavaScript, Videos, Iframes, Widgets und möglicherweise Bilder. Am performantesten ist dies entweder mit nativem Lazy-Loading (Laden und Wichtigkeitsattribute) oder durch Verwendung des Intersection Observer letzterer kann auch für performantes Scrollytelling, Parallaxe und Ads-Tracking verwendet werden.

      • Pushen Sie kritische CSS schnell.

        Sammeln Sie alle CSS, die erforderlich sind, um mit dem Rendern des ersten sichtbaren Teils der Seite zu beginnen („kritisches CSS“ oder „Above-the-fold“-CSS), und fügen Sie sie inline im <Head> der Seite ein. Ziehen Sie den bedingten Inline-Ansatz in Betracht. Alternativ können Sie auch HTTP/2-Server-Push verwenden, aber dann müssen Sie möglicherweise einen cache-fähigen HTTP/2-Server-Push-Mechanismus erstellen. Das Einfügen kritischer CSS in eine separate Datei auf der Root-Domain hat Vorteile, manchmal mehr als Inlining aufgrund des Caching.

      • Experimentieren Sie mit der Neugruppierung Ihrer CSS-Regeln.

        Ziehen Sie in Betracht, die Haupt-CSS-Datei in ihre einzelnen Medienabfragen aufzuteilen. Vermeiden Sie es, <link rel=“stylesheet“ /> vor asynchrone Snippets zu setzen. Wenn Skripte nicht von Stylesheets abhängen, ziehen Sie in Betracht, blockierende Skripte über blockierende Stile zu platzieren. Falls doch, teilen Sie das JavaScript in zwei Teile und laden Sie es auf beiden Seiten Ihres CSS. Zwischenspeichern Sie Inline-CSS mit einem Service-Mitarbeiter und experimentieren Sie mit In-Body-CSS. Dynamisches Styling kann teuer werden: Prüfen Sie, ob Ihre CSS-in-JS-Bibliothek die Ausführung optimiert, wenn Ihr CSS keine Abhängigkeiten von Thema/Requisiten aufweist, und komponieren Sie keine übermäßig gestylten Komponenten.

      • Antworten streamen.

        Streams bieten eine Schnittstelle zum Lesen oder Schreiben asynchroner Datenblöcke, von denen zu einem bestimmten Zeitpunkt nur eine Teilmenge im Speicher verfügbar sein kann. Anstatt eine leere UI-Shell zu bedienen und diese von JavaScript füllen zu lassen, lassen Sie den Service-Worker einen Stream konstruieren, bei dem die Shell aus einem Cache kommt, der Body jedoch aus dem Netzwerk. Das während der anfänglichen Navigationsanforderung gerenderte HTML kann dann den HTML-Streaming-Parser des Browsers voll ausnutzen.

      • Ziehen Sie in Betracht, Ihre Komponenten verbindungs bzw. gerätespeicherbewusst zu machen.

        Der „Save-Data“-Client-Hinweis-Anforderungs-Header ermöglicht es uns, die Anwendung und die Nutzlast an Benutzer mit Kosten und Leistungseinschränkungen anzupassen. Sie könnten z. B. Anfragen für Bilder mit hohem DPI-Wert in Bilder mit niedrigem DPI-Wert umwandeln, Web-Schriftarten und ausgefallene Parallaxeneffekte entfernen, die automatische Videowiedergabe, Server-Pushes abschalten oder sogar die Art und Weise ändern, wie Sie Markup liefern. Verwenden Sie die Netzwerkinformations-API zur Bereitstellung von Varianten schwerer Komponenten auf der Grundlage des Netzwerktyps. Passen Sie mit der Gerätespeicher-API auch Ressourcen dynamisch an den verfügbaren Gerätespeicher an.

      • Wärmen Sie die Verbindung auf, um die Bereitstellung zu beschleunigen.

        Verwenden Sie Ressourcenhinweise, um Zeit zu sparen bei dns-prefetch (DNS-Lookup im Hintergrund), preconnect (Starten des Verbindungs-Handshakes (DNS, TCP, TLS)), prefetch (Anfordern einer Ressource), preload (u. a. Ressourcen vorladen, ohne sie auszuführen) und prerender (holt Ressourcen im Voraus, führt aber kein JS aus und rendert keinen Teil der Seite im Voraus). Bei Verwendung des Vorladens, wie definiert werden muss oder nichts geladen wird; vorinstallierte Schriften ohne Cross-Origin-Attribut werden doppelt geholt. Beim Vorladen gibt es ein Rätsel der Prioritäten, also überlegen Sie sich, rel=“preload“-Elemente in das DOM zu injizieren, kurz vor den externen Blockier-Skripten.

      • Setzen Sie Service-Worker für Caching und Netzwerk-Fallbacks ein.

        Wenn Ihre Website Ã?ber HTTPS lÃ?uft, speichern Sie statische Assets in einem Service-Worker-Cache und speichern Sie Offline-Fallbacks (oder sogar Offline-Seiten) und rufen Sie sie vom Rechner des Benutzers ab, anstatt ins Netzwerk zu gehen. Speichern Sie die Applikationsshell im Cache des Service-Mitarbeiters zusammen mit ein paar kritischen Seiten, wie z.B. Offline-Seite oder Homepage. Aber: Stellen Sie sicher, dass der richtige CORS-Antwort-Header für ursprungsübergreifende Ressourcen vorhanden ist, speichern Sie keine undurchsichtigen Antworten im Cache und entscheiden Sie sich nicht für den CORS-Modus für ursprungsübergreifende Bilddateien.

      • Verwenden Sie Service-Mitarbeiter auf dem CDN/Edge (z.B. für A/B-Tests).

        Bei CDNs, die Service-Worker auf dem Server implementieren, sollten Service-Worker in Betracht gezogen werden, um die Leistung auch am Rand zu optimieren. Wenn z.B. bei A/B-Tests HTML seinen Inhalt für verschiedene Benutzer variieren muss, verwenden Sie Service-Mitarbeiter auf den CDNs, um die Logik zu handhaben. Oder streamen Sie das Neuschreiben von HTML, um Websites, die Google-Schriften verwenden, zu beschleunigen.

      • Optimieren Sie die Rendering-Leistung.

        Isolieren Sie teure Komponenten mit CSS-Einschlüssen. Stellen Sie sicher, dass beim Scrollen der Seite oder bei der Animation eines Elements keine Verzögerung auftritt und dass Sie durchgehend 60 Bilder pro Sekunde erzielen. Wenn das nicht möglich ist, dann ist es zumindest besser, die Frames pro Sekunde konsistent zu machen als einen gemischten Bereich von 60 bis 15. Verwenden Sie CSS-Änderungswille, um den Browser darüber zu informieren, welche Elemente sich ändern werden.

      • Haben Sie die Rendering-Erfahrung optimiert?

        Unterschätzen Sie nicht die Rolle der wahrgenommenen Leistung. Versuchen Sie, beim Laden von Assets dem Kunden immer einen Schritt voraus zu sein, damit sich die Erfahrung schnell anfühlt, während im Hintergrund ziemlich viel passiert. Um den Kunden bei der Stange zu halten, verwenden Sie Skelett-Bildschirme anstelle von Ladeindikatoren und fügen Sie Übergänge und Animationen hinzu.

      • Vermeiden Sie Layout-Verschiebungen (Rückflüsse) und Neulackierungen.

        Reflows werden durch neu skalierte Bilder und Videos, Webfonts, eingespeiste Anzeigen oder spät entdeckte Skripte verursacht, die Komponenten mit tatsächlichen Inhalten bestücken. Legen Sie Breiten und Höhenattribute für Bilder fest, damit moderne Browser die Box zuweisen und den Platz standardmäßig reservieren. Verwenden Sie einen SVG-Platzhalter, um die Anzeigebox zu reservieren, in der das Video und die Bilder erscheinen werden. Verwenden Sie hybrides Lazy-Loading, um ein externes Lazy-Loading-Skript nur dann zu laden, wenn natives Lazy-Loading nicht unterstützt wird. Gruppieren Sie Web-Schriftarten und passen Sie Zeilenhöhe und -abstand mit dem Schriftstil-Matcher an. Verfolgen Sie die Stabilität der Schnittstelle mit Layout Instability API und Cumulative Layout Shift (CLS). Netzwerk und HTTP/2

      • Ist das OCSP-Heften aktiviert?

        Wenn Sie OCSP-Heftung auf Ihrem Server aktivieren, können Sie TLS-Handshakes beschleunigen. Das OCSP-Protokoll erfordert nicht, dass der Browser Zeit mit dem Herunterladen und anschließenden Durchsuchen einer Liste nach Zertifikatsinformationen verbringt, wodurch die für einen Handshake erforderliche Zeit reduziert wird.

      • Haben Sie IPv6 bereits eingeführt?

        Studien zeigen, dass IPv6 Websites aufgrund von Nachbarschaftserkennung (NDP) und Routenoptimierung um 10 bis 15 % schneller macht. Aktualisieren Sie das DNS für IPv6, um auch in Zukunft kugelsicher zu bleiben. Stellen Sie einfach sicher, dass im gesamten Netzwerk Dual-Stack-Unterstützung bereitgestellt wird dadurch können IPv6 und IPv4 gleichzeitig nebeneinander laufen. Schließlich ist IPv6 nicht abwärtskompatibel.

      • Wird TCP BBR verwendet?

        BBR ist ein relativ neuer, verzögerungsgesteuerter TCP-Flusskontrollalgorithmus. Er reagiert auf tatsächliche Überlastungen und nicht wie TCP auf Paketverluste, und als solcher ist er wesentlich schneller, mit höherem Durchsatz und geringerer Latenz. Aktivieren Sie die BBR-Überlastungssteuerung und setzen Sie tcp_notsent_lowat auf 16KB für die HTTP/2-Priorisierung, um auf Linux-Kernels ab Version 4.9 zuverlässig zu arbeiten.

      • Machen Sie sich bereit für HTTP/2.

        HTTP/2 wird sehr gut unterstützt und bietet einen Leistungsschub. Es führt nirgendwo hin, und in den meisten Fällen sind Sie damit besser dran. Je nachdem, wie groß Ihre mobile Benutzerbasis ist, müssen Sie möglicherweise verschiedene Builds einsenden, und Sie könnten von der Anpassung eines anderen Build-Prozesses profitieren. (HTTP/2 ist in Netzwerken, die eine merkliche Paketverlustrate aufweisen, oft langsamer).

      • Setzen Sie HTTP/2 ordnungsgemäß ein.

        Sie müssen ein feines Gleichgewicht zwischen der Paketierung von Modulen und dem parallelen Laden vieler kleiner Module finden. Zerlegen Sie Ihre gesamte Schnittstelle in viele kleine Module; dann gruppieren, komprimieren und bündeln Sie sie. Teilen Sie sie auf Paketebene auf, oder indem Sie verfolgen, welche CSS/JS-Bausteine verwendet werden bzw. nicht verwendet werden. Trennen Sie Anbieter und Kundencode und trennen Sie Herstellerabhängigkeiten, die sich selten und häufig ändern. Das Senden von etwa 6-10 Paketen scheint ein anständiger Kompromiss zu sein (und ist für ältere Browser nicht allzu schlecht). Experimentieren Sie und messen Sie, um die richtige Balance zu finden.

      • Unterstützen Ihre Server und CDNs HTTP/2?

        Verschiedene Server und CDNs unterstützen HTTP/2 auf unterschiedliche Weise. Verwenden Sie Is TLS Fast Yet?, um Ihre Optionen zu prüfen oder schnell nachzuschlagen, welche Funktionen Sie erwarten können, unterstützt zu werden. Aktivieren Sie die BBR-Staukontrolle, setzen Sie tcp_notsent_lowat auf 16KB für die HTTP/2-Priorisierung.

      • Unterstützen Ihre Server und CDNs HTTP über QUIC (HTTP/3)?

        QUIC und HTTP/3 sind besser und kugelsicherer: mit schnelleren Handshakes, besserer Verschlüsselung, zuverlässigeren unabhängigen Streams, mehr Verschlüsselung und mit 0-RTT, wenn der Client zuvor eine Verbindung mit dem Server hatte. Allerdings ist es ziemlich CPU-intensiv (2-3x CPU-Nutzung für die gleiche Bandbreite). Prüfen Sie, ob Ihre Server oder CDNs HTTP over QUIC (auch als HTTP/3 bekannt) unterstützen und ob Sie es aktivieren können.

      • Wird HPACK-Kompression verwendet?

        Wenn Sie HTTP/2 verwenden, überprüfen Sie noch einmal, ob Ihre Server HPACK-Kompression für HTTP-Antwortheader implementieren, um unnötigen Overhead zu reduzieren. Da HTTP/2-Server relativ neu sind, unterstützen sie die Spezifikation möglicherweise nicht vollständig, wie z.B. HPACK. H2spec ist ein großartiges (wenn auch technisch sehr detailliertes) Werkzeug, um dies zu überprüfen.

      • Stellen Sie sicher, dass die Sicherheit auf Ihrem Server kugelsicher ist.

        Überprüfen Sie, ob Ihre Sicherheitskopfzeilen richtig eingestellt sind, beseitigen Sie bekannte Schwachstellen, und überprüfen Sie Ihr Zertifikat. Stellen Sie sicher, dass alle externen Plugins und Verfolgungsskripte über HTTPS geladen werden, dass Cross-Site-Scripting nicht möglich ist und dass sowohl HTTP Strict Transport Security-Header als auch Content Security Policy-Header richtig gesetzt sind.

Prüfung und Überwachung

      • Überwachen Sie Warnungen mit gemischtem Inhalt.

        Wenn Sie vor kurzem von HTTP zu HTTPS migriert haben, stellen Sie sicher, dass Sie sowohl aktive als auch passive Warnungen mit gemischten Inhalten mit Tools wie Report-URI.io überwachen. Sie können auch Mixed Content Scan verwenden, um Ihre HTTPS-fähige Website auf gemischte Inhalte zu scannen.

      • Haben Sie Ihren Auditing und Debugging-Workflow optimiert?

        Investieren Sie Zeit in die Untersuchung von Debugging und Auditing-Techniken in Ihrem Debugger, WebPageTest, Lighthouse und laden Sie Ihren Texteditor auf. Sie könnten z. B. WebPageTest von einer Google-Tabelle aus steuern und die Zugänglichkeits-, Leistungs und SEO-Ergebnisse in Ihr Travis-Setup mit der Lighthouse-CI oder direkt in Webpack integrieren.

      • Haben Sie in Proxy-Browsern und älteren Browsern getestet?

        Tests in Chrome und Firefox reichen nicht aus. Untersuchen Sie, wie Ihre Website in Proxy-Browsern und älteren Browsern (einschließlich UC Browser und Opera Mini) funktioniert. Messen Sie die durchschnittliche Internetgeschwindigkeit bei Ihrer Benutzerbasis, um große Überraschungen zu vermeiden. Testen Sie mit Netzwerk-Drosselung und emulieren Sie ein Gerät mit hohem DPI-Wert. BrowserStack ist fantastisch, aber testen Sie auch auf echten Geräten.

      • Haben Sie die Auswirkungen auf die Zugänglichkeit getestet?

        Große Seiten und DOM-Manipulationen mit JavaScript führen zu Verzögerungen bei den Ankündigungen der Screenreader. Fast Time to Interactive bedeutet, wie viel Zeit vergeht, bis der Screenreader die Navigation auf einer bestimmten Seite ankündigen kann und ein Screenreader-Benutzer tatsächlich auf die Tastatur drücken kann, um zu interagieren.

      • Ist eine kontinuierliche Überwachung eingerichtet?

        Eine gute Leistungsmetrik ist eine Kombination aus passiven und aktiven Überwachungswerkzeugen. Eine private Instanz von WebPagetest zu haben und Lighthouse zu verwenden, ist immer vorteilhaft für schnelle Tests, aber auch für die Einrichtung einer kontinuierlichen Überwachung mit RUM-Tools wie SpeedTracker, SpeedCurve und anderen. Setzen Sie Ihre eigenen User-Timing-Markierungen, um geschäftsspezifische Metriken zu messen und zu überwachen.

Schnelle Erfolge

      • Diese Liste ist recht umfassend, und die Fertigstellung aller Optimierungen könnte eine ganze Weile dauern. Wenn Sie also nur 1 Stunde Zeit hätten, um signifikante Verbesserungen zu erzielen, was würden Sie tun? Lassen Sie uns das Ganze auf 12 tief hängende Früchte herunterkochen. Natürlich sollten Sie vor dem Start und nach dem Ende die Ergebnisse messen, einschließlich der Renderingzeit und der Time To Interactive auf langsamen 3G-, langsamen 4G und Kabelverbindungen.
      • Messen Sie die realen Erfahrungen auf der Welt und setzen Sie sich entsprechende Ziele. Ein gutes anzustrebendes Ziel ist Größter zufriedenstellender Anstrich < 1 s, ein Geschwindigkeitsindex < 3s, Time to Interactive < 5s auf langsamen 3G, bei Wiederholungsbesuchen TTI < 2s. Optimieren Sie für die Rendering-Startzeit und die Zeit bis zur Interaktivität.
      • Bereiten Sie kritisches CSS für Ihre Hauptvorlagen vor und fügen Sie es in den <Kopf> der Seite ein. (Ihr Budget beträgt 14 KB). Arbeiten Sie bei CSS/JS innerhalb eines kritischen Budgets für die Dateigröße von max. 170 KB gezippt (0,7 MB dekomprimiert).
      • Schneiden, optimieren, verschieben und laden Sie so viele Skripte wie möglich, prüfen Sie leichtgewichtige Alternativen und begrenzen Sie die Auswirkungen von Skripten Dritter.
      • Servieren Sie Legacy-Code nur für Legacy-Browser mit dem Modul/Nomodul-Muster.
      • Experimentieren Sie mit der Neugruppierung Ihrer CSS-Regeln und testen Sie In-Body-CSS.
      • Fügen Sie Hinweise zu Ressourcen hinzu, um die Bereitstellung mit dns-lookup, preconnect, prefetch, preload, prerender zu beschleunigen.
      • Unterteilen Sie Web-Schriftarten in Untergruppen und laden Sie sie asynchron, und nutzen Sie die Anzeige von Schriftarten in CSS für eine schnelle erste Darstellung.
      • Optimieren Sie Bilder mit mozjpeg, guetzli, pingo und SVGOMG, und ziehen Sie in Betracht, WebP mit einem Bild-CDN zu bedienen.
      • Überprüfen Sie, ob HTTP-Cache-Header und Sicherheitskopfzeilen richtig eingestellt sind.
      • Aktivieren Sie die Brotli-Komprimierung auf dem Server. (Falls das nicht möglich ist, vergessen Sie nicht, die Gzip-Komprimierung zu aktivieren).
      • Aktivieren Sie die TCP BBR Überlastung, wenn Ihr Server mit dem Linux-Kernel Version 4.9+ läuft.
      • Aktivieren Sie OCSP-Hacking und IPv6, falls möglich.
      • Wenn HTTP/2 verfügbar ist, aktivieren Sie HPACK-Komprimierung und HTTP/3, wenn es auf CDNs verfügbar ist.
      • Cache-Assets wie Schriftarten, Stile, JavaScript und Bilder in einem Service-Worker-Cache.
      • Untersuchen Sie die Optionen zur Vermeidung von Rehydrierung, Verwendung von progressiver Hydratisierung und Streaming-Server-Side-Rendering für Ihre Einzelseitenanwendung.

Ein großes Dankeschön an Guy Podjarny, Yoav Weiss, Addy Osmani, Artem Denysov, Denys Mishunov, Ilya Pukhalski, Jeremy Wagner, Colin Bendell, Mark Zeman, Patrick Meenan, Leonardo Losoviz, Andy Davies, Rachel Andrew, Anselm Hannemann, Patrick Hamann, Andy Davies, Tim Kadlec, Rey Bango, Matthias Ott, Peter Bowyer, Phil Walton, Mariana Peralta, Philipp Tellis, Ryan Townsend, Ingrid Bergman, Mohamed Hussain S. H., Jacob Groß, Tim Swalling, Bob Visser, Kev Adamson, Adir Amsalem, Aleksey Kulikov und Rodney Rehm für die Durchsicht des Artikels sowie unserer fantastischen Gemeinschaft, die Techniken und Lehren aus ihrer Arbeit zur Leistungsoptimierung für alle nutzbar gemacht hat.

Sie sind wirklich umwerfend!