Page Load Time Opti­mie­rung für Mobile Netz­werke

20.6.2018 - David Gunzinger

Die mobile Lade­zeit wird von Google als wich­tiges Signal für die Bewer­tung von Seiten verwendet.Wir haben unsere Lade­zeit um 50% redu­ziert und sind damit an die Spitze der Ergeb­nis­liste bei bestimmten Such­an­fragen gelangt.

Page Load Time Optimierung für Mobile Netzwerke 
 teaser

Ausgangs­lage

Warum haben wir unsere Seite opti­miert?

  • Page­Rank : Google kündigte an, dass neu ab Juli 2018 die mobile Geschwin­dig­keit einen Einfluss auf den Page Rank haben wird. https://webmas­ters.goog­le­blog.com/2018/01/using-​page-speed-in-mobile-search.html

  • Mobile Anfragen : Wir sind spezia­li­siert auf Mobile Apps und unsere Website soll möglichst schnell auf mobilen Geräten geladen und darge­stellt werden.

  • Spass : Als Entwickler macht es Spass, Soft­ware zu opti­mieren.

Was ist speziell an mobilem Internet?

Mobiles Internet unter­scheidet sich zum Internet, welches an einem statio­nären Computer verwendet wird, vor allem durch die hohe Latenz.

Netz­werkBand­breiteRound Trip Time
edge240 Kbps840 ms
3g1600 Kbps300 ms
4g9000 Kbps170 ms
lte12000 Kbps70 ms
desktopN Kbps< 50ms

Wie sah die bishe­rige Archi­tektur aus?

Architektur Alt

Die Archi­tektur der Seite besteht aus einem Rails Backend mit Rails Admin, welches als CMS dient und einem Nodejs / React Frontend.

Vorgän­ging vorge­nom­mene Opti­mie­rungen

  • Http2 : Die Verwen­dung von HTTP2 erlaubt, dass alle Anfragen über eine Verbin­dung durch­ge­führt werden. Jeder Verbin­dungs­aufbau braucht mindes­tens 1x Round Trip Time für die TCP Verbin­dung, 1x Round Trip Time für das SSL Hand­shake und 1x Round Trip Time für den HTTP Request. Bei HTTP/1.1 müssten wir für ein Laden der Seite mindes­tens zweimal diesen Verbin­dungs­aufbau machen, bei HTTP2 nur einmal.

  • Server Side Rende­ring : Die ganze Webseite wird auf dem Server geren­dert, für das Navi­gieren auf der Seite werden jedoch nur die Diffe­renzen nach­ge­laden. Dies führt zu einem schnellen initialen Aufbau und einem mini­malen Aufwand für die Navi­ga­tion inner­halb der Seite. Die ganze Seite ist auch ohne Java­script benutzbar.

  • Hash URLs : Alle URL's für Ressourcen, wie z.B. Bilder, beinhalten einen Hash des Inhalts und sind mit einem Cache Header ausge­stattet, so dass sie nur einmal geladen werden müssen. Cache-​Control: public, max-age=31536000, immutable

  • Inline Style Sheets: Das Style­sheet, welches für den Aufbau der Seite benö­tigt wird, haben wir im React Teil direkt in die Antwort einge­bettet.

Mess­me­thoden

  • Page­speed : Der Klas­siker von Google, misst ob alle Cache Header, Kompri­mie­rungen, White­space Entfer­nungen und weiteres durch­ge­führt wurden.

  • Light­house : Ein Chrome Plug-In, welches dieselben Para­meter wie Page­speed misst. Zusätz­lich wird gemessen, ob die Seite barrie­re­frei nutzbar ist, ob über­zäh­lige CSS Styles vorhanden sind, und vieles mehr.

  • webpage­test.org: Erhebt die glei­chen Mess­daten wie Light­house, aller­dings lassen sich zusätz­lich Vergleichs­vi­deos erstellen und Leitungs­pro­file einstellen.

Messung der Ausgangs­lage:

Die folgende Grafik zeigt den Wasser­fall für das Laden der Seite mit 300ms Round Trip Time. Daraus wir ersicht­lich, dass enorm viele Bilder geladen werden, welche dem Benutzer nicht initial ange­zeigt werden.

Wasserfall Alt

Vorge­nom­mene Opti­mie­rungen

  • Bilder Lazy Laden : Es wurde der Inter­sec­tion­Ob­server verwendet, respek­tive ein Poly­fill für Browser, welche Inter­sec­tion­Ob­server nicht unter­stützen. Damit werden nur die Bilder initial geladen, welche der Benutzer ohne zu scrollen sieht. Für Benutzer die kein Java­script akti­viert haben, wurde mithilfe noscript das Bild normal geladen.

  • WebP : WebP ist ein neues Bild­format von Google, das Bilder bei glei­cher Qualität um mehr als 50% kompri­miert. Browser, welche WebP unter­stützen, senden im Accept Header des HTTP Requests ein Accept: image/webp mit. Bei unter­stützen Brow­sern wird eine WebP Version der Bilder ausge­lie­fert.

  • font-​display : Desi­gner setzten oft Custom Fonts ein. Diese blocken jedoch das Anzeigen des Textes bis sie geladen sind. Das CSS-​Attribut font-​display erlaubt es, den Text initial mit einem Fall­back Font anzu­zeigen bis der gewünschte Font vom Server geladen ist.

  • Http2 Server Push : HTTP2 ermög­licht es, initial ohne zusätz­li­chen Request, Ressourcen vom glei­chen Domain mitzu­senden. Dies ermög­licht einen Round Trip für die kriti­schen Ressourcen zu sparen. Um zu verhin­dern, dass Ressourcen an einen Client gesendet werden, welcher bereits darüber verfügt, wird das soge­nannte CASPER verwendet, cache-​aware server push. Dabei wird ein Cookie gesetzt, in dem der Wert ein kompri­mierter Bloom Filter der Hashes von den bereits gesen­deten Ressourcen ist. Als HTTP2-Server wurde h2o verwendet, welcher dies bereits von Haus aus unter­stützt.

  • Tcp initial conge­s­tion window : Tcp verwendet einen Algo­rithmus um das Über­füllen der Leitung zu verhin­dern. Dazu werden zuerst eine Reihe von Paketen geschickt (10 x 1500 Byte) und auf die Bestä­ti­gung gewartet. Dann wird die Grösse des Sende­fens­ters verdop­pelt. Dies führt jedoch bei Verbin­dungen mit hoher Band­breite, über Netz­werke mit hoher Latenz, zu Warte­zeiten in denen der Kommu­ni­ka­ti­ons­kanal nicht gefüllt werden kann. Die Mobile Hersteller (Apple, Micro­soft) sind sich dessen bewusst und haben folg­lich auf ihrer Seite die initiale Fens­ter­grösse auf 40-50 Pakete erhöht. Wie auch viele CDNs, haben auch wir das gemacht: ip route change default via [router-​ip] dev [device] proto static initcwnd 40 initrwnd 40

  • Caching : Das Rende­ring und die Kompres­sion einer Response dauert ca. 200ms. Für eine nahezu stati­sche Seite, wie der unseren, möchte man diese Zeit sparen. Die ganze Seite statisch vorzu­ren­dern funk­tio­niert leider nicht, da wir eine Suche nach Tags anbieten und wir so mit den kombi­na­to­ri­schen Möglich­keiten der Kompri­mie­rungen und der Bild­for­mate tausende von Seiten rendern müssten. Dafür haben wir die Archi­tektur ange­passt.

  • **Same Domain Fonts: ** Um die Fonts mittels HTTP2 Server Push zu senden, und keine zusätz­li­chesn 3x Round Trip Time Verbin­dungs­aufbau zu haben, werden sie neu von unserem Server ausge­lie­fert.

Opti­mie­rungen, die nicht den erhofften Erfolg gebracht haben:

  • **Nur kriti­sches Css inline: ** Aufgrund der hohen Round Trip Time und der hohen Band­breite ist es schneller, das CSS komplett inline auszu­lie­fern.

  • **Java­script file split: ** Aufgrund des glei­chen Grundes.

Archi­tektur Neu

Architektur Neu

In der neuen Archi­tektur wird die Kompres­sion direkt im Node / React Teil vorge­nommen. Varnish spei­chert von jeder Seite Vari­anten mit gzip und brotli Kompres­sion. Unkom­pri­mierte Aufrufe werden von Varnish durch Dekom­pres­sion gehand­habt. Es wird von jeder Seite auch eine Vari­ante mit WebP und eine mit "klas­si­schen" Bildern bereit­ge­stellt. Damit der initiale Aufruf einer Seite nicht zu lange dauert und damit Varnish weiss, wenn er Seiten wieder aus dem Cache entfernen muss, haben wir einen Preloader geschrieben. Der Preloader lädt die Einstiegs­punkte in allen Vari­anten neu und inva­li­diert den Cache für die Seiten mit der Suche sobald der Content im Rails CMS ange­passt wird.

Resultat

Der Wasser­fall ist deut­lich kleiner geworden, da wir nur noch jene Ressourcen laden, die dem Benutzer direkt ange­zeigt werden. Alle Antworten starten zur glei­chen Zeit, da wir HTTP2-​Server-push verwenden. Für das kriti­sche Bild im Header wird WebP verwendet, falls es vom Browser unter­stützt wird.

Wasserfall Neu

Wie man im Video sieht, hat sich die Lade­ge­schwin­dig­keit mit einem LTE Netz­werk­profil mehr als verdop­pelt.

Kontakt

Smoca AG
Tech­no­park­strasse 2
Gebäude A, 3. Stock
8406 Winter­thur

Letzter Blog­ein­trag

Does it Matter ? Ein Bericht zur Entwick­lung um den IoT-​Standard der ZukunftSaliha Chelouti - 7.7.2022

Das Smar­thome war bis mehr ...

  • Smoca Facebook
  • Smoca Twitter
  • Smoca LinkedIn
  • Smoca RSS Feed