Beim Seitenaufbau einer Webseite mit vielen Javascript- und CSS-Dateien kommt es oft dazu, dass man als Besucher beobachten kann wie der Webbrowser das Layout nacheinander darstellt. Das ist besonders dann der Fall, wenn eingebundene Javascript-Dateien das Rendering blockieren, weil sie noch nicht vollständig geladen wurden. Aber auch wenn für das Layout (oder Teile davon) mehrere einzelne CSS-Ressourcen eingebunden werden und der Besucher zum Beispiel eine langsame Internetverbindung hat.
An dieser Stelle kommt Facebook's Pipeline-Technik "BigPipe" in's Spiel. Mit BigPipe kann man eine Website in einzelne Fragmente zerlegen, die Pagelets genannt werden. Jedes Pagelet besteht mindestens aus seinem HTML-Code und optional aus zugehörigen Javascript- und CSS-Ressourcen.
Webseite mit BigPipe in einzelne Fragmente aufteilen
Wenn das HTML auf dem Server erzeugt wird, wird es nicht direkt an der eigentlichen Stelle im HTML-Dokument ausgegeben, sondern an der Stelle wird nur ein Platzhalter-Element rein geschrieben, das leer ist. Dieses Platzhalter-Element bekommt dann eine eindeutige ID, damit die BigPipe-Javascript-Bibliothek das Element später identifizieren und den echten HTML-Code injizieren kann. Bevor das passiert werden allerdings erst einmal die zum Pagelet zugehörigen CSS-Ressourcen eingebunden. Der zum Pagelet zugehörige HTML-Code wird erst dann in das Platzhalter-Element injiziert, wenn die CSS-Ressource vollständig geladen ist!
Wenn von allen Pagelets die CSS-Ressourcen geladen sind und der HTML-Code in die Platzhalter-Element injiziert wurde, dann beginnt BigPipe mit dem Nachladen der externen Javascript-Ressourcen aller bekannten Pagelets. Jedes einzelne Pagelet wird also die Pipeline durchlaufen und nacheinander gerendert.
Priorisieren von Pagelets: Die wichtigsten Pagelets zuerst
Der Besucher will beim Besuch einer Webseite möglichst schnell die relevanten Informationen sehen. Komplett sinnfrei wäre es also, wenn bei einer langsamen Internetverbindung plötzlich zuerst der Footer der Seite, dann die Sidebar, dann die Navigation und dann erst die eigentlichen Inhalte gerendert werden würden.
Da der eigentliche HTML-Code eins Pagelets jetzt aber nicht mehr direkt an die entsprechende Stelle im HTML-Dokument geschrieben wird, sondern dort nur Platzhalter eingesetzt werden, ist es möglich, die einzelnen Pagelets serverseitig zu priorisieren. So kann man zum Beispiel dem Pagelet für den Hauptinhalt eine höhere Priorität geben als dem Pagelet für die Sidebar. BigPipe würde tatsächlich zuerst den Hauptinhalt rendern und dann erst die weniger relevanten Teile (ganz egal, ob die Endposition von z.B. der Navigation im fertigen DOM noch vor dem Hauptinhalt liegt).
BigPipe: Download der PHP- und Javascript-Klassen [PHP >= 5.4]
Da Facebook offiziell den Quellcode für BigPipe nicht bereitstellt, haben sich andere Entwickler schon mal hingesetzt und die Pipeline-Technik nachgebaut. Allerdings ist der Code von dieser GitHub-Quelle leider nicht unbedingt für den Produktiveinsatz geeignet. Er ist überladen und zudem noch inkompatibel wenn man auf der Website die Hauptinhalte per Transport-Iframe (eine andere Geschichte...) nachladen will und diesen Response ebenfalls durch die Pipeline leiten möchte. Da ich aber derzeit an einem Projekt arbeite, in dem all das Standard sein soll und ich auf eine (stabil funktionierende) Pipeline-Technik nicht verzichten wollte, habe ich das Teil komplett neu geschrieben und mich dabei an dieser GitHub-Quelle orientiert was den Aufbau der Klassen etc. angeht.
Ich hoffe, dass sich die Arbeit gelohnt hat und ich vielleicht auch anderen damit helfen kann. Für mich hat es sich auf jeden Fall gelohnt, weil ich dadurch einiges über Javascript gelernt habe. Unter folgendem Link auf GitHub sind alle benötigten Dateien mit einer index.php
, die als Demoseite fungiert.
GitHub-Repository: https://github.com/Nerdmind/BigPipe