« Zum Blog

Shopware Ladezeiten Challenge Teil IV - Integrieren der Einkaufswelten

Einkaufswelten beschleunigen

Nach langer Zeit gibt es hier wieder einen neuen Blogeintrag. Diesen Eintrag möchte ich mit einem kurzem Recap beginnen. Mein Ziel in 2017 ist es die Ladezeit einer Shopware Installation auf 2 Sekunden in 3G Netzwerken zu reduzieren. Zusätzlich dazu möchte ich einen Google PageSpeed Wert von 90 für sowohl Mobil als auch Desktop erreichen. Getestet wird das Ganz mit den Google Developer Tools sowie - natürlich - mit dem Google PageSpeed Wert.

Da dieser Blogpost ein Teil einer Serie ist, hier zuerst einmal alle Links:

Der heutige Blogeintrag ist in diese Punkte aufgeteilt:

Was genau war das Problem?

Das Standardtheme von Shopware basiert auf zwei Bestandteilen: dem Grundgerüst der Seite sowie der Einkaufswelt. Das Grundgerüst des jeweiligen Onlineshops sieht dabei so aus:

Es wird also der Header geladen und der eigentliche Inhalt der Seiten, also die Einkaufswelt, wird später über eine zusätzliche Anfrage nachgeladen. Rein im Sinne der Ladezeiten gesprochen, ist das kein gutes Vorgehen. Die erste Abfrage könnte schon den gesamten Inhalt an den Webbrowser senden, der diesen direkt anzeigen kann. Stattdessen muss der Browser erst die Antwort erhalten, das HTML parsen und kann dann die zweite Anfrage anschicken. (Rein technisch sind es sogar 3 Anfragen, da das Grundgerüst erst noch das Shopware JavaScript nachladen muss, bevor der Inhalt angefragt wird.)

Hier ist das ganze noch einmal visuell:

In dem Diagramm kann man sehen, dass das HTML nach ca. 0,5 Sekunden beim Browser ankommt (blauer kurzer Balken vor dem grünen Balken - Zeile 4). In Zeile 5 wird nun das JavaScript geladen, auch ab ca. 0,5 Sekunden. Die Anfrage wird bis 1,2 Sekunden geladen und ab 1,4 Sekunden wird das JavaScript ausgeführt. (Helllila Bereich, der sich über alle Zeilen streckt.) Ab 1,5 Sekunden wird nun die Einkaufswelt angefragt. Diese Anfrage ist bei 1,6 Sekunden beantwortet. Alles in allem kann die Einkaufswelt bei 1,6 Sekunden in die Seite eingefügt werden, statt bei 0,5. (Die Bilder sind aber immer noch nicht heruntergeladen - Mattem, lila Balken, die folgen.)

Zusammenfassend lässt sich also sagen, dass der Inhalt 1,1 Sekunden später geladen wird, als eigentlich nötig. Das geht besser.

Die Technik dahinter

Die Lösungsmöglichkeit ist ganz einfach: Inhalte direkt in die Seite integrieren… zumindest theoretisch… praktisch eher weniger. Hier ist warum (Kleiner Tipp, wenn du technisch nicht so interessiert bist, kannst Du direkt zum nächsten Abschnitt springen.):

Wenn die Einkaufswelt später korrekt angezeigt wird, muss ihr HTML in dieses DIV Element eingefügt werden.

<div class="content--emotions">
     <div class="emotion--wrapper" data-controllerUrl="/widgets/emotion/index/emotionId/4/controllerName/index" data-availableDevices="0,1,2,3">
     </ div>
     <div class="emotion--wrapper" data-controllerUrl="/widgets/emotion/index/emotionId/7/controllerName/index" data-availableDevices="4">
     </ div>
</ div>

Zuerst einmal sieht man hier, dass für die Gerätegrößen 0,1,2 & 3 und die Gerätegröße 4 jeweils eine andere Einkaufswelt angezeigt werden soll. Vereinfacht gesagt, entsprechen die Gerätegrößen großen Bildschirmen (0), normalen Desktops (1), großen Tablets (2), Tablets / großen Smartphones (3) und kleinen Smartphones (4). Wenn man nun den Inhalt direkt in die Seite einfügen möchte, muss serverseitig festgestellt werden, welche Größe die Einkaufswelt haben muss. (Was nicht zuverlässig möglich ist.)

Nehmen wir aber an, dass der Server die richtige Einkaufswelt korrekt bestimmen kann und das HTML in das jeweilige Tag eingesetzt wird. Das Ergebnis, wie könnte es anders sein:

Solltest Du Dich fragen, wo der Inhalt ist: er wird versteckt. Sobald der Ladespinner angezeigt wird, werden alle Elemente ausgeblendet, die die Einkaufswelt beinhalten. Es gilt allerdings zu beachten, wenn der dynamisch eingefügte Ladespinner per JS entfernt wird, stellt das Standardtheme sicher, dass der Spinner wieder angezeigt wird.

Um diesen Blogeintrag nicht allzu lange zu machen, ist hier des Rätsels Lösung: In dem Moment, in dem das DOMContentReady Event gefeuert wird, verarbeitet Shopware alle Einkaufswelten. Sollte die Ladeanzeige entfernt worden sein, so wird diese wieder in das Dokument eingefügt. Diese Standardverhalten kann man zum Glück überschreiben, wenn man die Verarbeitungsmethode der Einkaufswelten ersetzt.

Zugegebenermaßen ist das nicht die einzige Schwierigkeit, über welche man stolpert. Angefangen von einem falschen Layout über nicht funktionierende Pfeile sowie Probleme beim Laden der Einkaufswelten in einem Request mitsamt dem Grundgerüst gibt es noch eine ganze Reihe weiterer Probleme, die es zu beseitigen gilt.

Der WOTipps Einkaufswelten​beschleuniger

Um all diesen Problemen Herr zu werden, habe ich ein weiteres Plugin geschrieben: WOTipps Einkaufswelten​beschleuniger. Dieses Plugin sorgt nicht nur dafür, dass die Einkaufswelten schnell geladen werden, sondern beseitigt auch all diese Probleme. Das spart viel Zeit und ist für Webmaster einfacher zu nutzen, als eine eigene Anpassung pro Shop.

Der fertige Prozess sieht damit wie folgt aus:

Das Ergebnis sieht im Demoshop so aus:

Bzw. der Google PageSpeed Wert reagiert wie folgt.

Zusätzlich dazu werden die Einkaufswelten sofort angezeigt, wenn der Layoutmodus Resize oder Fluid genutzt wird. Dafür wird der eingebettete Inhalt direkt verarbeitet. Das hat den Vorteil, dass man nicht auf das DOMContentReady Event warten muss. Das Problem dieses Events ist, dass alle nicht-asynchronen JavaScript Dateien heruntergeladen werden, bevor das Event gefeuert wird. Das kostet wieder wertvolle Sekunden.

Die Beschleunigung kommt damit vor allem bei schlechten Internetverbindungen zum Tragen.

Zusammenfassung

In diesem Blogeintrag wurden beleuchtet, warum sich Einkaufswelten negative auf die Ladezeiten eines Shopwareshops auswirken. Dabei habe ich

Alles in allem kann ich jedem Empfehlen die Einkaufswelten zumindest direkt in die Startseite einzubetten. Es bringt durchaus einen großen Performanceboost.

 

« Zum Blog