Der Turbo für Websites: BigPipe im Einsatz
Die Ladezeit einer Website ist einer der wichtigsten Faktoren für ihren Erfolg. Die Zahl der Seitenabbrüche steigt rapide, je länger ein User auf Content warten muss. Bereits nach einer Sekunde sind etwa zehn Prozent aller User wieder abgesprungen.
Frei nach dem Motto „viel hilft viel“ sind im Cloud-Zeitalter schnell riesige Server-Farmen bereit gestellt, um die Auslieferung der kompletten Seite zu beschleunigen. Genau hier beginnt aber bereits das Problem, denn üblicherweise wird eine komplette Seite zunächst gerendert und erst danach ausgeliefert, sodass der User sie sehen kann.
Mit ein paar kleinen Tricks hat Facebook jedoch bereits 2010 die Performance seiner Website gefühlt verdoppelt, indem es die Seite partiell ausliefert und den Ladevorgang parallelisiert. Zwar ist die Technologie dahinter relativ einfach zu integrieren und auch schon seit längerem vorhanden. Dennoch ist sie im Web-Alltag derzeit eher selten zu finden.
Ajax-Requests
Besonders im Web 2.0 laden viele Websites Content via Ajax nach. Der Server rendert und liefert die initiale Webseite aus. Einzelne Elemente verarbeitet der Server aufgrund neuer Anfragen jedoch erst nachgelagert und sendet sie anschließend an den Browser. Besonders für interaktive Elemente ist dies eine sehr gute Möglichkeit, um komplett neue Seitenaufrufe zu minimieren und dem User eine bessere Usability zu bieten.
Der Nachteil dieser Lösung ist allerdings, dass ständig neue Anfragen an den Server gehen. Sie erzeugen durch den HTTP-Standard einen Overhead und müssen gerade bei einer statuslosen Sprache wie PHP eventuell auch das Framework oder CMS komplett neu initialisieren. Bei größeren Systemen wie TYPO3 oder Magento gehen hier wertvolle Zeit und Systemleistungen verloren. Ein weiteres Problem ist, dass Suchmaschinen Content, der mit Ajax nachgeladen wird, nicht finden und somit wichtige Bestandteile im Suchindex fehlen können.
BigPipe
Genau diese Probleme adressiert BigPipe. Hierbei geht nur eine einzige Anfrage an den Server, sodass es weniger Overhead gibt. Außerdem finden die Such-Robots den kompletten Content am Ende der Anfrage einer Seite. Dabei generiert der Server zunächst nur den Rahmen der Webseite und schickt diesen an den Browser – direkt danach arbeitet der Server jedoch im selben Prozess weiter, ohne die aktuelle Anfrage zu beenden und rendert nun die komplexeren Teile der Webseite, um sie nach und nach auszuliefern.
Die einzelnen Content-Teile bezeichnet man im Fachjargon als „Chunks“, das mehrfache Aussenden von Content innerhalb einer Anfrage als „Flush“. Üblicherweise erfolgt der Flush nur am Ende einer Anfrage mit einem einzigen großen Chunk. Ein Server kann ihn aber prinzipiell beliebig oft forcieren und damit zum gefühlten Performance-Boost beitragen: Der User erhält schnell immer wieder ein neues Häppchen.
Darüber hinaus lassen sich die CSS- und JS-Ressourcen parallel zur Erzeugung und Auslieferung der Inhalte laden. So berechnet und sendet man bei BigPipe zunächst nur den kompletten Content innerhalb des head-Tags. Der Browser, der nun bereits die Links zu externen Ressourcen kennt, lädt diese noch während der restliche Inhalt erzeugt wird. Dieses parallele Abarbeiten der Anfragen spart massiv Wartezeit.
Pagelets
Facebook nennt die einzelnen Blöcke „Pagelets“. So sind insbesondere langsamere Komponenten – wie der News-Feed oder der Chat – als eigene Pagelets implementiert. Zum Teil sind die Pagelets auch ineinander verschachtelt. So ist streng genommen das erste Pagelet der komplette Inhalt des body-Tags, da ja bereits der head-Block gesendet wurde, um die CSS-Ressourcen zu laden. Die Einteilung der Pagelets sollte man sich gut überlegen. Zum Beispiel sollte schon eine Art Fallback oder Ladeanzeige zu sehen sein, während der Content noch lädt, damit der User weiß, dass sich hier noch etwas ändert.
Sobald aber das Grundgerüst (inklusive der Kopfgrafiken, der Navigation und allen weiteren Elementen) steht, kann der User auf der Webseite navigieren, obwohl diese möglicherweise noch gar nicht zu Ende geladen ist. Er bekommt direkt ein Feedback von der Seite, statt vor einem weißen Browser-Fenster zu sitzen. Ja, er kann sogar schon Entscheidungen entsprechend seiner User-Journey treffen.
Performance
Da die verschiedenen Browser die Flushes und Content-Renderings unterschiedlich verarbeiten, unterscheidet sich auch der gefühlte Performance-Gewinn von Browser zu Browser. Wie groß der subjektive Geschwindigkeitszuwachs jedoch sein kann sieht man, wenn man Facebook einmal als BigPipe– und einmal in der Standard-Variante mit traditionellem Laden anschaut.
In diesem Beispiel kann man wunderbar sehen, wie lange Facebook in Wirklichkeit braucht, um den kompletten Content zu generieren. Das fällt gewöhnlich aber keinem Nutzer auf, da innerhalb eines Sekundenbruchteils bereits der Rahmen steht und einzelne, wichtige Blöcke zur Verfügung stehen. Der Chat erscheint als letztes, was jedoch nicht auffällt, da dieser nur ein Randelement der Seite ist.
So ist es zum Beispiel in einem Shop-System sinnvoll, die personalisierten Empfehlungen per BigPipe später zu laden. Der Grund: Diese Informationen muss man dynamisch berechnen, was längere Zeit braucht. Dazu kommt, dass der User ohnehin erst den zweiten oder dritten Blick auf diesen Block wirft, der bis dahin dann auch zur Verfügung steht.
Der BigPipe Auslieferungsprozess auf einen Blick |
|
Implementierungen
Es gibt bereits diverse Libraries und Extensions, die die BigPipe-Funktionalität integrieren. Für eine reine PHP-Website bietet sich etwa die Library von Juho Mäkinen an, welche auf Github zur Verfügung steht. Die mitgelieferte example.php zeigt, wie sich die einzelnen Pagelets definieren lassen. Die komplette Logik zum Ersetzen der Pagelets ist in der Datei bigpipe.js zu finden, die die Funktionalitäten der Prototype-Library nutzt.
Auch für das bekannte CMS Drupal gibt es bereits ein eigenes Modul, das aber noch keinen stabilen Stand erreicht hat. Ausgiebiges Testen ist daher zunächst wichtig.
Die Ankündigung, ein BigPipe-Modul für Magento bereitzustellen, hat in der Community sehr schnell für ein überaus positives Feedback gesorgt. Gerade in dem verbreiteten E-Commerce-System sorgen oft einzelne Blöcke – die sich aufgrund der Personalisierung nicht komplett cachen lassen – für längere Gesamtladezeiten. Mit dem entsprechenden BigPipe- Modul kann man über die Layout-XML einzelne Blöcke als Pagelets für BigPipe definieren und sogar sortieren.
Auch außerhalb der PHP-Welt gibt es in Sachen BigPipe Bewegung. So befindet sich ein eigenes kleines Framework auf Basis von Node.js mit dieser Technik im Aufbau. Generell ist die Implementierung von BigPipe denkbar einfach (selbst wenn kein Modul für ein System zur Verfügung steht) und lässt sich auch in bestehende Websites integrieren.
HTTP 2.0
HTTP 2.0 wird zukünftig noch einen Schritt weitergehen: Mit Hilfe von Multiplexing und Pipelining kann man hierbei sämtliche externe Dateien wie Bilder oder auch JavaScript-Dateien in einer einzigen Verbindung ausliefern. Dadurch lässt sich nochmal Overhead beim Aufbau der Verbindung und gegebenenfalls sogar der Initialisierung der Anwendung sparen – sofern die Daten nicht statisch vorliegen.
Fazit
Dass sich lange Ladezeiten schlecht auf die Conversion auswirken, ist schon lange kein Geheimnis mehr. Ausführliche Tests mehrerer Anbieter haben dies längst bestätigt. Wer an gefühlter Performance gewinnen möchte, kann seinen Content intelligent in Pagelets aufteilen, via Flush versenden und die CSS- und JS-Dateien parallel laden. Die Implementierung ist mit den bereits zur Verfügung stehenden Libraries denkbar einfach und schnell gemacht. Entsprechende Überlegungen, welche Elemente per BigPipe-Technologie ausgeliefert werden sollen, sollten bei jedem Projekt dazu gehören, da der Aufwand im Verhältnis zum Nutzen mit etwas Erfahrung sehr gering ist.
Ebenfalls interessant:
Das Drupal Modul ist wohl nicht wirklcih erwähnenswert, Drupal 6 würde ich für eine Seite nicht mehr einsetzen und der letzte Commit in dem Projekt ist von 2011…
„Bereits nach einer Sekunde sind etwa zehn Prozent aller User wieder abgesprungen.“ … das halte ich für übertrieben. Zunächst muss der Besucher ja bemerken, dass die Ladezeit länger als gewöhnlich ist …
Gibt es nichts aktuelleres mehr dazu?
Schon beim letzten Artikel dazu ist mir aufgefallen, dass der letzte Commit im Git Jahre her war, wie Donngal schon sagte