Verbesserung der Leistung eines Online-Shops (Fallstudie)
Veröffentlicht: 2022-03-10Jeder Front-End-Entwickler jagt denselben heiligen Gral der Leistung: grüne Ergebnisse in Google Page Speed. Greifbare Zeichen für gute Arbeit werden immer geschätzt. Wie bei der Jagd nach dem Gral muss man sich allerdings fragen, ob das wirklich die gesuchte Antwort ist. Die reale Leistung für Ihre Benutzer und wie sich die Website „anfühlt“, wenn Sie sie verwenden, sollte nicht außer Acht gelassen werden, auch wenn es Sie ein oder zwei Punkte an Seitengeschwindigkeit kostet (sonst hätten wir alle nur eine Suchleiste und ungestylt Text).
Ich arbeite in einer kleinen Digitalagentur, und mein Team arbeitet hauptsächlich an großen Unternehmenswebsites und -geschäften – die Seitengeschwindigkeit kommt irgendwann in die Diskussion, aber normalerweise lautet die Antwort zu diesem Zeitpunkt, dass eine große Neufassung erforderlich wäre, um wirklich etwas zu erreichen. ein unglücklicher Nebeneffekt von Größe und Projektstruktur in Konzernen.
Die Zusammenarbeit mit jewellerybox im Online-Shop war für uns eine willkommene Abwechslung. Das Projekt bestand darin, die Shop-Software auf unser eigenes Open-Source-System zu aktualisieren und das Frontend des Shops von Grund auf neu zu erstellen. Das Design wurde von einer Design- und UX-Agentur erstellt, die auch den HTML-Prototyp (basierend auf Bootstrap 4) betreut hat. Von dort haben wir es in die Vorlagen integriert – und ausnahmsweise hatten wir einen Kunden, der auch von der Leistung der Website besessen war.
Für den Start haben wir uns hauptsächlich darauf konzentriert, das neue Design auf den Markt zu bringen, aber als der Relaunch der Website online ging, haben wir begonnen, unsere Aufmerksamkeit darauf zu richten, die roten und orangen Punkte in grüne umzuwandeln. Es war eine mehrmonatige Reise voller schwieriger Entscheidungen, mit vielen Diskussionen darüber, welche Optimierungen es wert waren, weiterverfolgt zu werden. Heute ist die Website viel schneller und schneidet in verschiedenen Showcases und Benchmarks hoch ab. In diesem Artikel werde ich einige der Arbeiten hervorheben, die wir geleistet haben, und wie wir unsere Geschwindigkeit erreichen konnten.
Online-Shops sind etwas anders
Bevor wir ins Detail gehen, nehmen wir uns einen kurzen Moment Zeit, um darüber zu sprechen, wie sich Online-Shops von vielen anderen Websites unterscheiden (wenn Sie das bereits wissen, treffen wir uns im nächsten Abschnitt mit Ihnen). Wenn wir über eine E-Commerce-Website sprechen, haben Sie folgende Hauptseiten:
- die Homepage (und „Inhalts“-Seiten),
- Kategorie- und Suchseiten,
- Produktdetailseiten,
- der Einkaufswagen und die Kasse (offensichtlich).
In diesem Artikel konzentrieren wir uns auf die ersten drei und die Leistungsanpassungen für diese. Die Kasse ist ihr eigenes Biest. Dort haben Sie viel zusätzliches JavaScript und Back-End-Logik, um die Preise zu berechnen, sowie mehrere Serviceanrufe, um den geeigneten Versandanbieter und Preisschätzungen basierend auf dem Land, in das versendet wird, zu erhalten.
Dies erfolgt natürlich zusätzlich zur Validierung der Formularfelder , die Sie zum Aufzeichnen der Rechnungs- und Lieferadressen benötigen. Fügen Sie dazu das Drop-In des Zahlungsanbieters hinzu, und Sie haben selbst einige Seiten, die niemand anfassen möchte, sobald sie ordnungsgemäß getestet wurden und funktionieren.
Woran denken Sie als erstes, wenn Sie sich einen Online-Shop vorstellen? Bilder – viele, viele Produktbilder. Sie sind im Grunde überall und werden Ihr Design dominieren. Außerdem möchten Sie viele Produkte zeigen, um die Leute dazu zu bringen, bei Ihnen zu kaufen – also ein Karussell. Aber warte! Klicken die Leute auf die darin enthaltenen Produkte? Wir können es herausfinden, indem wir das Karussell verfolgen. Wenn wir es verfolgen, können wir es optimieren! Und plötzlich haben wir externe, KI-gestützte Produktkarussells auf unseren Seiten.
Die Sache ist die, dass ein Karussell nicht das letzte geschwindigkeitsbeeinträchtigende Element sein wird, das Sie der Seite hinzufügen, um mehr Produkte zu präsentieren, in der Hoffnung, mehr Verkäufe anzuziehen. Natürlich braucht ein Shop interaktive Elemente , sei es das Zoomen von Produktbildern, einige Videos, ein Countdown bis zum heutigen Versandtermin oder ein Chatfenster, um mit dem Kundensupport in Kontakt zu treten.
All dies ist sehr wichtig, wenn Sie Conversions direkt als Umsatz messen . Außerdem wird alle paar Monate jemand im Team einige coole neue Funktionen entdecken, die hinzugefügt werden könnten, und so beginnen sich die Komplexität und das JavaScript zu häufen, obwohl Sie mit den besten Absichten begonnen haben, es schlank zu halten.
Und während Sie normalerweise die gesamte Seite eines Artikels zwischenspeichern können, gilt dies nicht für viele Shopseiten und -elemente. Einige sind benutzerspezifisch, wie der Warenkorb in der Kopfzeile oder die Wunschliste, und sollten aufgrund der persönlichen Natur der Daten niemals zwischengespeichert werden. Wenn Sie physische Waren haben, haben Sie es außerdem mit Live-Inventar zu tun: Besonders während des Weihnachtstrubels benötigen Sie genaue und aktuelle Informationen über den Lagerbestand; Sie benötigen also eine komplexere Caching-Strategie , die es Ihnen ermöglicht, Teile der Seite zwischenzuspeichern und alles während des serverseitigen Renderns wieder zusammenzufügen.
Doch schon in der Planungsphase lauern Fallstricke. In einer Design- und oft auch in der Prototypenphase arbeiten Sie mit ausgefeilten Produktnamen und -beschreibungen in nahezu einheitlicher Länge und idealen Produktbildern. Sie sehen toll aus! Das einzige Problem? In Wirklichkeit können Produktinformationen sehr unterschiedlich lang sein , was Ihr Design durcheinander bringen kann. Bei mehreren tausend Produkten können Sie nicht jedes einzelne prüfen.
Daher hilft es, wenn Designer oder die Leute, die den Prototypen machen, mit sehr kurzen und sehr langen Saiten testen, um sicherzustellen, dass das Design noch passt. Ebenso kann es für einen Shop ein großes Problem sein, wenn Informationen zweimal im HTML erscheinen, einmal für Desktop und einmal für Mobilgeräte – insbesondere wenn es sich um komplexe Informationen wie Produktdetails, den Warenkorb oder Facetten für die Filter einer Produktkategorie handelt Seite. Es ist schwierig, diese synchron zu halten – also helfen Sie bitte einem anderen Entwickler und tun Sie es nicht.
Eine andere Sache, die niemals vernachlässigt werden sollte und ab der Prototypenphase integriert werden sollte, ist die Barrierefreiheit. Mehrere Tools da draußen können Ihnen bei einigen der Grundlagen helfen, von alternativem Text für alle Bilder und Symbole mit einer Funktion über Farbkontraste bis hin zu dem Wissen, welche ARIA-Attribute wo verwendet werden sollen (und wann nicht). Es ist viel einfacher, dies von Anfang an zu integrieren als später, und es ermöglicht allen, die Website, an der Sie arbeiten, zu genießen.
Hier ist ein Tipp: Wenn Sie noch nie gesehen haben, dass Menschen einen Bildschirmleser verwenden oder nur mit einer Tastatur navigieren, finden Sie Videos dazu leicht auf YouTube. Es wird Ihr Verständnis dieser Themen verändern.
Zurück zur Performance: Warum ist es so wichtig, die Performance eines Shops wieder zu verbessern? Die offensichtliche Antwort ist, dass Sie möchten, dass die Leute bei Ihnen kaufen . Es gibt mehrere Möglichkeiten, wie Sie dies beeinflussen können, und die Geschwindigkeit Ihrer Website ist eine große. Studien zeigen, dass jede zusätzliche Sekunde Ladezeit einen erheblichen Einfluss auf die Conversion Rate hat. Darüber hinaus ist die Seitengeschwindigkeit ein Rankingfaktor für die Suche und auch für Ihre Google-Anzeigen. Die Verbesserung der Leistung wirkt sich also spürbar auf das Endergebnis aus.
Praktische Dinge, die wir getan haben
Einige Leistungsengpässe sind leicht zu erkennen, aber eine gründliche Verbesserung ist ein längerer Weg mit vielen Drehungen und Wendungen. Wir haben mit all den üblichen Dingen begonnen, wie z. B. das erneute Überprüfen des Cachings von Ressourcen, sehen, was wir vorab abrufen oder asynchron laden können, und stellen sicher, dass wir HTTP/2 und TLSv1.3 verwenden. Viele davon werden in der hilfreichen Übersicht von CSS-Tricks behandelt, und das Smashing Magazine bietet eine großartige PDF-Checkliste.
Das Wichtigste zuerst: Auf allen Seiten geladene Dinge
Reden wir über Ressourcen und nicht nur über CSS oder JavaScript (auf die wir später noch eingehen werden). Wir begannen damit, Dinge zu betrachten, die auf mehreren Bildschirmen geteilt wurden, von denen jede einen Einfluss haben kann. Erst danach haben wir uns auf Seitentypen und die damit verbundenen Probleme konzentriert. Einige gemeinsame Elemente waren die folgenden.
Symbol wird geladen
Wie bei so vielen Websites verwenden wir mehrere Symbole in unserem Design. Der Prototyp enthielt einige benutzerdefinierte Symbole, die eingebettete SVG-Symbole waren. Diese wurden als ein großes svg
-Tag im HTML-Kopf der Seite gespeichert, mit einem Symbol für jedes der Symbole, das dann als verknüpftes svg
im HTML-Body verwendet wurde. Dies hat den netten Effekt, dass sie dem Browser beim Laden des Dokuments direkt zur Verfügung stehen, aber offensichtlich kann der Browser sie nicht für die gesamte Website zwischenspeichern.
Also haben wir uns entschieden, sie in eine externe SVG-Datei zu verschieben und vorab zu laden. Außerdem haben wir nur die Symbole aufgenommen, die wir tatsächlich verwenden. So kann die Datei auf dem Server und im Browser zwischengespeichert werden und es müssen keine überflüssigen SVGs interpretiert werden. Wir unterstützen auch die Verwendung von Font Awesome auf der Seite (die wir über JavaScript laden), aber wir laden es bei Bedarf (Hinzufügen eines winzigen Skripts, das nach <i>
-Tags sucht, und dann Laden des Font Awesome-JavaScripts, um beliebige SVG-Dateien zu erhalten Symbole, die es findet). Da wir uns an unsere eigenen Symbole "above the fold" halten, können wir das gesamte Skript ausführen, nachdem das DOM geladen wurde.
An manchen Stellen verwenden wir Emojis auch für farbenfrohe Symbole, etwas, woran keiner von uns wirklich gedacht hat, aber um das unsere Inhaltsredakteurin Daena gebeten hat und das eine großartige Möglichkeit ist, Symbole ohne jegliche negative Auswirkung auf die Leistung anzuzeigen (der einzige Vorbehalt ist die unterschiedlichen Designs auf verschiedenen Betriebssystemen).
Laden von Schriftarten
Wie auf so vielen anderen Websites verwenden wir Webfonts für unsere typografischen Anforderungen. Das Design erfordert zwei Schriftarten im Hauptteil ( Josefin Sans in zwei Strichstärken), eine für Überschriften ( Nixie One ) und eine für speziell gestalteten Text ( Moonstone Regular ). Von Anfang an haben wir sie lokal mit einem Content Delivery Network (CDN) für die Leistung gespeichert, aber nachdem wir den wunderbaren Artikel von Simon Hearne über das Vermeiden von Layoutverschiebungen beim Laden von Schriftarten gelesen hatten, experimentierten wir damit, die fettgedruckte Version zu entfernen und die normale zu verwenden.
In unseren Tests war der visuelle Unterschied so gering, dass keiner unserer Tester es erkennen konnte, ohne beide gleichzeitig zu sehen. Also haben wir die Schriftstärke fallen lassen . Während der Arbeit an diesem Artikel und der Vorbereitung einer visuellen Hilfe für diesen Abschnitt sind wir auf größere Unterschiede zwischen Chromium-basierten Browsern auf dem Mac und WebKit-basierten Browsern auf hochauflösenden Bildschirmen gestoßen (yay, Komplexität!). Dies führte zu einer weiteren Diskussionsrunde darüber, was wir tun sollten.
Nach einigem Hin und Her haben wir uns entschieden, den Faux Bold beizubehalten und -webkit-text-stroke: 0.3px
zu verwenden, um diesen bestimmten Browsern zu helfen. Der Unterschied zur Verwendung der tatsächlichen separaten Schriftstärke ist gering, aber nicht genug für unseren Anwendungsfall, in dem wir fast keine fette Schrift verwenden, sondern nur eine Handvoll Wörter gleichzeitig (sorry, Schriftliebhaber).
Darüber hinaus können mehrere Produkte mit Gravuren personalisiert werden . Diese Gravuren können in mehreren Schriftarten ausgeführt werden, und für einige bieten wir eine Vorschau mit der angewendeten Schriftart an. Für diese laden wir die Schriftart bei Bedarf herunter, wenn sie in der Dropdown-Schriftartauswahl ausgewählt wird. Die Vorschauen in der Dropdown-Liste sind Beispielbilder, wie die Schriftart aussieht. Dadurch müssen wir nicht 10 oder mehr zusätzliche Schriftdateien herunterladen.
Legacy-Unterstützung
Eines Tages überraschte mich CSS-Tricks mit einem Artikel zum Thema „How to Favicon in 2021“. Wir haben jede Touch-Icon-Größe der Welt verwendet – der Artikel hat mich dazu gebracht, neu zu bewerten, was wir tatsächlich brauchen, und mir gezeigt, dass manchmal das, was vor ein paar Jahren galt, vielleicht nicht mehr benötigt wird. Basierend auf dem Artikel haben wir unsere Favicon- und Touch-Icon-Listen auf die empfohlenen Versionen beschränkt.
In ähnlicher Weise haben wir auch eine Schriftart, die wir nur als WOFF-Version hatten, in WOFF2 konvertiert , das viel kleiner ist, und wir haben uns entschieden, WOFF2 für Schriftarten bereitzustellen (wobei WOFF als Fallback verbleibt). Und wir haben nicht mehr benötigte CSS-Anweisungen bereinigt.
Lazy und On-Demand-Laden
Mehrere Metriken konzentrieren sich auf die Zeit, nach der Benutzer mit der Seite interagieren können. Die Logik diktiert, dass weniger zu ladende Elemente bedeuten, dass dieser Punkt früher erreicht wird. Um dem Rechnung zu tragen, ist es wichtig, sich zu fragen, welche Teile der Seite wesentlich sind und welche der Benutzer erst später benötigt. Wir haben diesbezüglich viele Diskussionen und Versuche und Irrtümer durchgemacht.
Der Wasserfall der Netzwerkaktivität hat hier sehr geholfen, aber auch das Denken an Benutzerströme. Beispielsweise kann das gezoomte Produktbild geladen werden, wenn ein Benutzer zum ersten Mal mit dem Produktbild interagiert, und Bilder in der Fußzeile werden normalerweise nicht „above the fold“ angezeigt und können später geladen werden. Wenn Sie sich Sorgen über Verlangsamungen machen, können Sie dennoch mit dem Vorabruf von Ressourcen arbeiten.
Eine Sache, die uns schon sehr früh aufgefallen ist, war die große Wirkung des Chat-Clients. Es waren allein über 500 KB JavaScript, und obwohl ich leider kein Diagramm mehr habe, war es auch langsam zu laden. Obwohl das JavaScript so eingestellt war, dass es asynchron geladen wurde, hat Google es in die Time-to-Interactive-Messungen aufgenommen.
Wir konnten nicht vollständig nachvollziehen, warum dies der Fall war, aber angesichts dessen und der schieren Größe begannen wir, nach Alternativen zu suchen, anstatt zu versuchen, etwas zu reparieren, über das wir nur begrenzte Kontrolle hatten. Wir haben Jewellerybox davon überzeugt, stattdessen ein selbst gehostetes Open-Source-Chat-Widget auszuprobieren, das uns mehr Kontrolle darüber gibt, wie es geladen wird, und das auch viel kleiner ist. Um es weiter zu verbessern, laden wir zunächst nur das Symbol für den Chat; der Rest wird geladen, wenn Sie darauf klicken, um ihn zu öffnen.
Das unsichtbare Drittanbieter-Karussell
Jewellerybox wollte einen Drittanbieterdienst ausprobieren, der KI nutzt, um die Produktpersonalisierung in den Karussells auf mehreren Seiten zu verbessern. Wir haben uns dafür entschieden, seine API vom Backend aus aufzurufen, damit wir mehr Kontrolle darüber haben, was geladen wird (ohne große JavaScript-Abhängigkeiten) und wie lange wir auf eine Antwort von ihrem Dienst warten (mit einigen definierten Fallbacks). Aus diesem Grund werden die Karussells auf die gleiche Weise wie die nicht personalisierten geladen und können auch mit einem eindeutigen Cache-Schlüssel zwischengespeichert werden.
Es gibt jedoch einen Nachteil: Dies bedeutet, dass die anfängliche Seitenwiedergabe auf der Serverseite langsamer sein könnte, wenn sie nicht zwischengespeichert wird. Aus diesem Grund arbeiten wir derzeit an alternativen Möglichkeiten, die Ergebnisse nach dem Laden der Seite einzufügen und zunächst einen Platzhalter zu rendern.
Zweitens: Optimierung von JavaScript – ein harter Kampf gegen externe Feinde
Das Karussell bringt uns zum zweiten großen Bereich, auf den wir uns konzentriert haben: JavaScript. Wir haben das JavaScript geprüft, das wir hatten, und der Großteil stammt aus Bibliotheken für verschiedene Aufgaben, mit sehr wenig benutzerdefiniertem Code. Wir haben den Code, den wir selbst geschrieben haben, optimiert, aber natürlich können Sie nur einen Bruchteil Ihres Gesamtcodes tun – die großen Gewinne liegen in den Bibliotheken.
Das Optimieren von Dingen in Bibliotheken oder das Herausnehmen von Teilen, die Sie nicht benötigen, ist aller Wahrscheinlichkeit nach ein Kinderspiel. Sie wissen nicht wirklich, warum einige Teile dort sind, und Sie werden die Bibliothek nie wieder ohne viel manuelle Arbeit aktualisieren können. Vor diesem Hintergrund sind wir einen Schritt zurückgegangen und haben uns angesehen, welche Bibliotheken wir verwenden und wofür wir sie benötigen , und wir haben für jede untersucht, ob es eine kleinere oder schnellere Alternative gibt, die genauso gut zu unseren Anforderungen passt.
In mehreren Fällen gab es! Zum Beispiel haben wir uns entschieden, die Slick-Slider-Bibliothek durch GliderJS zu ersetzen, das weniger Funktionen hat, aber alle, die wir brauchen, außerdem ist es schneller zu laden und hat eine modernere CSS-Unterstützung! Darüber hinaus haben wir viele der eigenständigen Bibliotheken aus der Haupt-JavaScript-Datei entfernt und damit begonnen, sie bei Bedarf zu laden.
Da wir Bootstrap 4 verwenden, binden wir immer noch jQuery in das Projekt ein, arbeiten aber daran, alles durch native Implementierungen zu ersetzen. Für Bootstrap selbst gibt es auf GitHub eine bootstrap.native-Version ohne die jQuery-Abhängigkeit, die wir jetzt verwenden. Es ist kleiner und läuft schneller. Außerdem generieren wir zwei Versionen unserer Haupt-JavaScript-Datei: eine ohne Polyfills und eine mit Polyfills, und wir tauschen die Version mit ihnen aus, wenn der Browser sie benötigt, sodass wir den meisten Menschen eine optimierte Hauptversion liefern können. Wir haben einen „Polyfill-on-Demand“-Service getestet, aber die Leistung entsprach nicht unseren Erwartungen.
Eine letzte Sache zum Thema jQuery. Zunächst haben wir es von unserem Server geladen. Wir haben Leistungsverbesserungen auf unserem Testsystem gesehen, als es über das Google CDN geladen wurde, aber Page Speed Insights hat sich über die Leistung beschwert (ich frage mich, wer das lösen könnte), also haben wir das Hosting selbst erneut getestet, und in der Produktion war es aufgrund des tatsächlich schneller CDN, das wir verwenden.
Lektion gelernt : Eine Testumgebung ist keine Produktionsumgebung, und Fixes für die eine gelten möglicherweise nicht für die andere.
Drittens: Bilder – Formate, Größen und all dieser Jazz
Bilder machen einen großen Teil dessen aus, was einen Online-Shop ausmacht. Eine Seite wird normalerweise mehrere Dutzend Bilder haben, noch bevor wir die verschiedenen Versionen für verschiedene Geräte zählen. Die Jewellerybox-Website gibt es seit fast 10 Jahren, und viele Produkte waren die meiste Zeit über verfügbar, sodass Originalproduktbilder in Größe und Stil nicht einheitlich sind und die Anzahl der Produktaufnahmen ebenfalls variieren kann.
Idealerweise möchten wir responsive Bilder für verschiedene Ansichtsgrößen und Darstellungsdichten in modernen Formaten anbieten, aber jede Änderung der Anforderungen würde viel Umstellungsarbeit bedeuten. Aus diesem Grund verwenden wir derzeit eine optimierte Größe von Produktbildern, aber wir haben keine responsiven Bilder dafür. Das zu aktualisieren ist auf der Roadmap aber nicht trivial. Inhaltsseiten bieten mehr Flexibilität, und dort generieren und verwenden wir verschiedene Größen und schließen sowohl WebP- als auch Fallback-Formate ein.
Durch so viele Bilder wird die anfängliche Nutzlast erheblich gewichtiger. Wann und wie Bilder geladen werden, wurde also zu einem großen Thema. Lazy-Loading klingt wie die Lösung, aber wenn es universell angewendet wird, kann es anfänglich sichtbare Bilder verlangsamen, anstatt sie direkt zu laden (oder zumindest fühlt es sich für den Benutzer so an). Aus diesem Grund haben wir uns für eine Kombination aus direktem Laden der ersten paar und Lazy-Loading des Rests entschieden, indem wir eine Kombination aus nativem Lazy-Loading und einem Skript verwendet haben.
Für das Website-Logo verwenden wir eine SVG-Datei, für die wir eine erste Version vom Kunden erhalten haben. Das Logo ist eine komplizierte Schriftart, in der Teile der Buchstaben fehlen, wie sie in einem unvollkommenen Druck von Hand wären. In großen Größen müssten Sie die Details zeigen, aber auf der Website verwenden wir sie nie über 150 x 30 Pixel. Die Originaldatei war 192 KB groß, nicht riesig, aber auch nicht superklein. Wir haben uns entschieden, mit dem SVG zu spielen und die Details darin zu verringern, und am Ende haben wir eine Version, die entpackt 40 KB groß ist. Es gibt keinen visuellen Unterschied bei den von uns verwendeten Displaygrößen.
Zu guter Letzt: CSS
Kritisches CSS
CSS spielt eine große Rolle im Chrome User Experience Report (CrUX) von Google und spielt auch im Google Page Speed Insights-Bericht und in den Empfehlungen eine wichtige Rolle. Eines der ersten Dinge, die wir getan haben, war die Definition kritischer CSS, die wir direkt in den HTML-Code laden, damit sie dem Browser so schnell wie möglich zur Verfügung stehen – dies ist Ihre Hauptwaffe im Kampf gegen Content Layout Shifts (CLS). Wir haben uns für eine Kombination aus automatisierter Extraktion des kritischen CSS auf Basis einer Prototypseite und einem Mechanismus entschieden, mit dem wir zu extrahierende Klassennamen (inklusive aller Unterregeln) definieren können. Wir tun dies separat für allgemeine Stile, Produktseitenstile und Kategoriestile, die auf den jeweiligen Seitentypen hinzugefügt werden.
Etwas, das wir daraus gelernt haben und das zwischendurch einige Fehler verursacht hat, ist, dass wir aufpassen müssen, dass die Reihenfolge von CSS dadurch nicht geändert wird. Zwischen verschiedenen Personen, die den Code schreiben, jemandem, der später in der Datei eine Überschreibung hinzufügt, und einem automatischen Tool, das Dinge extrahiert, kann es chaotisch werden.
Explizite Dimensionen gegen CLS
Für mich ist CLS etwas, das Google aus seinem Hut gezogen hat, und jetzt müssen wir uns alle damit befassen und unsere kollektiven Köpfe darum wickeln. Während wir früher Container einfach ihre Größe von den darin enthaltenen Elementen erhalten ließen, kann das Laden dieser Elemente jetzt die Boxgröße durcheinander bringen. Vor diesem Hintergrund haben wir die Registerkarte „Leistung“ in den Entwicklertools und den äußerst hilfreichen Layout-Shift-GIF-Generator verwendet, um zu sehen, welche Elemente CLS verursachen. Von dort aus betrachteten wir nicht nur die Elemente selbst, sondern auch ihre Eltern und analysierten die CSS-Eigenschaften, die sich auf das Layout auswirken würden. Manchmal hatten wir Glück – zum Beispiel brauchte das Logo nur eine explizite Größeneinstellung auf Mobilgeräten, um eine Layoutverschiebung zu verhindern – aber manchmal war der Kampf echt.
Profi-Tipp: Manchmal wird eine Verschiebung nicht durch das scheinbare Element verursacht, sondern durch das vorangehende Element. Um mögliche Übeltäter zu identifizieren, konzentrieren Sie sich auf Eigenschaften, die sich in Größe und Abstand ändern. Die grundlegende Frage, die Sie sich stellen sollten, lautet: Was könnte dazu führen, dass sich dieser Block bewegt?
Da sich so viele Bilder auf der Seite befinden, hat es uns auch einige Arbeit bereitet, sie mit CLS korrekt zu verhalten. Daran erinnert Barry Pollard zu Recht in seinem Artikel „Setting Height and Width on Images Is Important Again“. Wir haben viel Zeit damit verbracht, die richtigen Breiten- und Höhenwerte (plus Seitenverhältnisse) für unsere Bilder in jedem Fall herauszufinden, um sie wieder in das HTML einzufügen. Dadurch gibt es für die Bilder keine Layout-Verschiebung mehr, da der Browser die Informationen früher bekommt.
Der Fall des mysteriösen CLS-Scores
Nachdem wir viele der großen CLS-Probleme oben auf der Seite entfernt hatten, stießen wir auf eine Straßensperre. Manchmal (nicht immer) haben wir beim Betrachten von Page Speed oder Lighthouse einen CLS-Score von über 0,3 erhalten, aber nie auf der Registerkarte „Leistung“. Der Layout Shift GIF Generator zeigte es manchmal, aber es sah so aus, als würde sich der gesamte Seitencontainer bewegen .
Mit aktivierter Netzwerk- und CPU-Drosselung haben wir es endlich in den Screenshots gesehen! Der Header auf Mobilgeräten wuchs aufgrund der darin enthaltenen Elemente um 2 Pixel in der Höhe . Da der Header auf Mobilgeräten sowieso eine feste Höhe hat, haben wir uns für die einfache Lösung entschieden und eine explizite Höhe hinzugefügt – Fall geschlossen. Aber es hat uns viele Nerven gekostet und es zeigt, dass die Werkzeuge hier noch sehr ungenau sind.
Das funktioniert nicht – Wiederholen wir es!
Wie wir alle wissen, sind die mobilen Werte für die Seitengeschwindigkeit viel härter als für den Desktop, und ein Bereich, in dem sie für uns besonders schlecht waren, waren die Produktseiten. Der CLS-Score war durch die Decke gegangen, und die Seite hatte auch Leistungsprobleme (mehrere Karussells, Registerkarten und nicht zwischenspeicherbare Elemente werden dies tun). Erschwerend kommt hinzu, dass das Layout der Seite dazu führte, dass einige Informationen verschoben oder doppelt hinzugefügt wurden.
Auf dem Desktop haben wir grundsätzlich zwei Spalten für den Inhalt:
- Spalte A : Das Produktfoto-Karussell, manchmal gefolgt von Blogger-Zitaten, gefolgt von einem Tab-Layout mit Produktinformationen.
- Spalte B : Der Produktname, der Preis, die Beschreibung und die Schaltfläche „In den Warenkorb“.
- Reihe C : Das Produktkarussell ähnlicher Produkte.
Auf Mobilgeräten musste das Produktfoto-Karussell jedoch zuerst kommen, dann Spalte B, dann das Registerkarten-Layout aus Spalte A. Aus diesem Grund wurden bestimmte Informationen im HTML dupliziert, die durch display: none
gesteuert wurden, und die Reihenfolge wurde angezeigt geschaltet mit der Eigenschaft flex: order
. Es funktioniert definitiv, aber es ist nicht gut für CLS-Ergebnisse, weil im Grunde alles neu geordnet werden muss.
Ich entschied mich für ein einfaches Experiment in CodePen: Könnte ich das gleiche Grundlayout von Boxen auf dem Desktop und auf Mobilgeräten erreichen, indem ich das HTML überdenke und display: grid
anstelle von flexbox verwende, und würde mir das erlauben, die Rasterbereiche nach Bedarf einfach neu anzuordnen? Um es kurz zu machen, es hat funktioniert und CLS gelöst, und es hat den zusätzlichen Vorteil, dass der Produktname jetzt viel früher im HTML-Code erscheint als zuvor – ein zusätzlicher SEO-Gewinn!
Hacken eines Karussells für CLS
Das Wort „Karussell“ tauchte schon mehrfach auf – und das aus gutem Grund. Wir haben nicht nur die von uns verwendete Karussellbibliothek geändert (und das Ladeverhalten der darin enthaltenen Bilder geändert), wir mussten uns auch für CLS damit auseinandersetzen, da wir mehrere Seiten haben, auf denen das Karussell "above the fold" ist und daher könnte einen großen Einfluss auf die Geschwindigkeitswerte haben.
Wir begannen damit, das Karussell später zu laden, um die Zeit bis zur Interaktion zu verkürzen, aber das führte zu einer sichtbaren Verzögerung, bis das JavaScript ausgelöst wurde und die Folien sich von untereinander in eine Reihe bewegten. Wir haben viele Möglichkeiten ausprobiert, das CSS zu schreiben, um dies zu verhindern und alles in einer Zeile zu halten, einschließlich des Ausblendens des gesamten Karussells, bis es vollständig geladen wurde. Nichts hat uns die Art von Lösung gegeben, die wir gerne als Benutzer beim Besuch eines Shops gesehen hätten.
Entschuldigen Sie diese kurze Tirade, aber wirklich, Produkt- und Kategoriekarussells sind der perfekte Sturm flexibler Elemente in einem responsiven Shop: Bilder haben möglicherweise keine universelle Höhe, Produktnamen können sich über mehrere Zeilen erstrecken, und Sie können Labels haben oder auch nicht. Im Grunde läuft es darauf hinaus: Es ist keine feste Höhe für die Reihe möglich, und die Breite kennt man auch nicht wirklich. Lustige Zeiten.
Am Ende haben wir uns entschieden, alle Folien (außer der ersten) auf visibility: hidden
bis das Karussell vollständig geladen ist, an diesem Punkt fügen wir dem Karussell eine Klasse hinzu, um alle Folien wieder sichtbar zu machen . Dies löst das Problem, dass es zunächst zusätzliche Höhe einnimmt.
Außerdem setzen wir zunächst flex-shrink: 0
und flex-base: 340px
für die Folien in einer Non-Wrapping-Flexbox. Dadurch befinden sie sich in einer einzigen Zeile und geben eine ungefähre Anfangsbreite für die Folien an. Nachdem dieses Rätsel gelöst war – und ja, es war so viel Kopfzerbrechen, wie es sich anhört – haben wir einige Korrekturen hinzugefügt, um Platz für die Punkte und Pfeile zu schaffen, in die sie fallen können. Damit gibt es fast keinen CLS mehr für die Karussells!
Rückblick ist 20 ⁄ 20
Am Ende waren es viele kleine Änderungen über mehrere Monate, die unsere Ergebnisse verbessert haben, und wir sind noch nicht fertig. Wir haben hauptsächlich mit zwei Leuten an den Frontend-Verbesserungen gearbeitet, während sich der Rest des Teams auf die Verbesserung des Backends konzentrierte. Dies war zwar wahrscheinlich etwas langsamer, stellte aber sicher, dass es keine Überschneidungen gab und die Unterschiede in den Bewertungen eindeutig zugeordnet werden konnten. Einige Ressourcen, die sehr geholfen haben, waren die großartigen Artikel hier im Smashing Magazine über die eigenen Verbesserungen des Magazins.
Irgendwann werden die Dinge, die Sie ausprobieren sollten, nicht offensichtlich, weil Sie nicht glauben, dass sie einen großen Unterschied machen sollten, aber irgendwann danach stellen Sie fest, dass sie es tun. Darüber hinaus hat uns dieses Projekt erneut gelehrt, wie wichtig es ist, die Leistung und die Metriken dafür von Anfang an im Auge zu behalten, von der Vorstellung des Designs und der Codierung des Prototyps bis zur Implementierung in den Vorlagen. Kleine Dinge, die früh vernachlässigt werden, können sich zu riesigen Bergen summieren, die Sie später erklimmen müssen, um sie rückgängig zu machen.
Hier sind einige der wichtigsten Aspekte , die wir gelernt haben:
- Das Optimieren von JavaScript ist nicht so effektiv wie das Laden bei Bedarf;
- Das Optimieren von CSS scheint mehr Punkte zu gewinnen als das Optimieren von JavaScript;
- Schreiben Sie CSS-Klassen unter Berücksichtigung von CLS und der Extraktion von kritischem CSS;
- Die Tools zum Auffinden von CLS-Problemen sind noch nicht perfekt. Denken Sie über den Tellerrand hinaus und prüfen Sie mehrere Tools;
- Bewerten Sie jeden Drittanbieterdienst, den Sie integrieren, auf Dateigröße und Leistungszeit. Schieben Sie wenn möglich die Integration von allem zurück, was alles verlangsamen würde;
- Testen Sie Ihre Seite regelmäßig auf CrUX-Änderungen (und insbesondere auf CLS);
- Prüfen Sie regelmäßig, ob alle Ihre bisherigen Supporteinträge noch benötigt werden.
Wir haben noch Dinge auf unserer Liste der Verbesserungen zu machen:
- Wir haben immer noch viel unbenutztes CSS in der Hauptdatei, das entfernt werden könnte;
- Wir möchten jQuery vollständig entfernen. Dies bedeutet, Teile unseres Codes neu zu schreiben, insbesondere im Kassenbereich;
- Weitere Experimente müssen durchgeführt werden, um die externen Schieberegler einzubeziehen;
- Unsere mobilen Punktzahlen könnten besser sein. Insbesondere für Mobilgeräte sind weitere Arbeiten erforderlich.
- Responsive Bilder müssen für alle Produktbilder hinzugefügt werden;
- Wir werden die Inhaltsseiten speziell auf eventuell erforderliche Verbesserungen überprüfen, insbesondere in Bezug auf CLS.
- Elemente, die das Collapse-Plugin von Bootstrap verwenden, werden durch das native HTML-
details
-Tag ersetzt; - Die DOM-Größe muss reduziert werden;
- Wir werden einen Drittanbieterdienst für schnellere und bessere Suchergebnisse integrieren. Dies wird mit einer großen JavaScript-Abhängigkeit einhergehen, die wir integrieren müssen;
- Wir werden daran arbeiten, die Zugänglichkeit zu verbessern, indem wir uns sowohl automatisierte Tools ansehen als auch selbst einige Tests mit Screenreadern und Tastaturnavigation durchführen.
Weitere Ressourcen
- „DevTools-Debugging-Tipps und Verknüpfungen (Chrome, Firefox, Edge)“, Vitaly Friedman, Smashing Magazine
- „Einige Performance-Blog-Beiträge, die ich in letzter Zeit mit Lesezeichen versehen und gelesen habe“, Chris Coyier, CSS-Tricks
- „Ein ausführlicher Leitfaden zur Messung von Core Web Vitals“, Barry Pollard, Smashing Magazine
- „Von semantischem CSS zu Rückenwind: Refactoring der Netlify-UI-Codebasis“, Charlie Gerard und Leslie Cohn-Wein, Netlify
- „CSS Auditing Tools“, Iris Lješnjanin, Smashing Magazine
- „Dinge, die Sie heute mit CSS machen können“, Andy Bell, Smashing Magazine
- „So verbessern Sie die CSS-Leistung“, Milica Mihajlija, Calibre
- „Die Lücke bei der mobilen Leistungsungleichheit, 2021“, Alex Russell
- „Maximale Optimierung des Ladens von Bildern für das Web im Jahr 2021“, Malte Ubl
- „Das bescheidene
<img>
-Element und grundlegende Web-Vitals“, Addy Osmani, Smashing Magazine