Ladezeit von Webseiten optimieren – Wir zeigen wie!
Schon seit knapp 2 Jahren beschäftigen wir uns nun intensiv mit der Optimierung von Ladezeiten bei Webseiten. Damit scheint die Zeit reif, unsere Erfahrungen darüber zu veröffentlichen.
Ladezeit – Zunächst ein wenig Theorie zum Verständnis
Wenn der Browser eine Webseite darstellen soll, sendet er eine Anfrage an den örtlich zuständigen Server. Im Prinzip fragt der Browser zunächst einmal bei dem Server an, auf welchem die Seite gespeichert (gehostet) wurde, ob dieser auch verfügbar ist. Bekommt der Browser die Information „Klar, ich bin bereit“ lässt er sich alle Informationen (Daten) schicken, die er zum anzeigen des Inhalts dieser einen Seite benötigt.
Auf diesem „Transportweg“ kommt es häufig zu Stauungen und Verstopfungen weil viele Daten gleichzeitig übertragen werden wollen oder müssen. Wenn es zu diesen Verstopfungen kommt, bleibt die anzuzeigende Webseite weiß oder es erscheinen die Bilder und Texte zeitversetzt nach und nach. Ich denke jeder wird das kennen!
Doch warum kommt es zu diesen Verzögerungen während die Seite lädt?
Die Technikfreaks mögen mir verzeihen wenn ich die Sachverhalte im Folgenden nicht ganz richtig schildere – aber nach meinen Erfahrungen im Erklären dieser Optimierungsstrategie habe ich festgestellt, dass die Probleme und Ansätze von Laien so am besten verstanden werden.
Eine Webseite besteht aus vielen unterschiedlichen Daten. Zunächst will ich das HTML nennen, dem „Konstruktions- & Bauplan“ der darzustellenden Seite. Dann gehören noch Bilder dazu, Angaben zum Aussehen (dem „Webdesign“) der Seite – CSS, in aller Regel benötigt die Seite noch JavaScripte für verschiedene Funktionen und Cookies muss der Browser auch noch gesetzt bekommen. Je größer, ansprechender und animierter die Seite später sein soll, umso größer die Anzahl der einzelnen Dateien und auch das gesamte Ladevolumen aller Dateien zusammen.
All diese Daten führen dazu, dass der Browser langsamer lädt
Dabei macht dem Browser nicht unbedingt die Gesamtgröße aller Dateien zu schaffen – das zentrale Problem im optimieren der Ladezeit ist, dass viele Dateien zur gleichen Zeit geladen werden müssen. Der Server versucht also alle Dateien durch die Internetleitung zu quetschen. Wenn man also über eine schnelle DSL Leitung (z. Bsp.: Glasfaserkabel) verfügt, ist die Ladezeit einer Webseite tatsächlich schneller. Der Vergleich hinkt stark, aber im Grunde hängt das vom Kabelquerschnitt ab: Je dicker das Kabel umso mehr passt gleichzeitig hindurch!
Der SEO hat aber nun keine Chance die Internetleitung seiner Zielgruppe zu optimieren, also müssen andere Möglichkeiten her:
Die neuralgischen Schwachpunkte beim laden einer Webseite
Ausgehend vom tatsächlichen Ablauf eines sog. HTTP Requests (jener Anfrage an den Server, die zum Transport der benötigten Webelemente / Daten führt) konzentriert sich der Optimierungsansatz auf folgende Bestandteile
- Der Server
Streng genommen fängt die Optimierung schon hier an: Haben Sie ein günstiges Hostingpaket bei einem Massenanbieter oder zahlen Sie etwas mehr und gönnen sich den Luxus eines eigenen Servers. Im letzteren Fall könnten Sie dann schonmal ausschliessen, dass andere hoch frequentierten Webseiten massiv Ihren Server durch viele Prozesse überlasten. Wenn nur Ihre Webseite oder wenige andere auf dem Server gespeichert worden, fällt mehr Prozessorleistung auf die einzelne Webseite ab und diese wird dadurch schneller vom Server an den Browser ausgeliefert. An dieser Stelle hat der SEO meist nur wenig Einfluss, ein Gespräch mit dem Admin und auch dem Anbieter des Servers lohnt aber oft trotzdem weil Feinjustierungen oft schon ein paar Millisekunden bringen. Bei der Ladezeit kommt es – wie beim normalen SEO auch – immer auf viele Details an. Die Seite lädt subjektiv und objektiv schneller, wenn an vielen Stellen wenige Millisekunden eingespart werden konnten. - Die Internetleitung
Wie weiter oben schon erläutert – je „dicker“ die Leitung umso mehr Daten passen gleichzeitig hindurch! Je mehr Daten gleichzeitig durch die Leitung an den Browser geschickt werden, umso schneller kann dieser die angefragte Seite auch darstellen – die Seite lädt also schneller. Der Optimierungsansatz für den SEO tendiert hier aber gegen „Null“. - Der PC des Nutzers
Auch hier schlummern Potentiale wenn der PC / Rechner des Anwenders mit vielen anderen Programmen beschäftigt ist oder mittlerweile „in die Jahre gekommen“ ist und eigentlich mal ausgetauscht werden sollte. Auch hier hat der SEO in aller Regel keine Chance zu optimieren. - Der Browser des Nutzers
Hier wird es schon interessanter! Zwar kann der SEO den Browser in seinen technischen Einstellungen nicht verändern und damit die Ladezeit beinflussen – aber er kann die Daten vom Server so schicken lassen, dass sie besonders gut und damit schnell vom Browser verarbeitet werden können. Zusammen mit den nächsten Punkten hat der SEO hier die grössten Erfolge beim verringern der Ladezeiten von Webseiten. - Der Quellcode
Im Quellcode hat der SEO die direktesten Einwirkungsmöglichkeiten auf die Ladezeiten. Ein nach W3C valider Quellcode, richtige Verschachtelung der HTML Elemente, konsequentes Befolgen der Vererbung bei CSS Anweisungen und ein insgesamt schlanker Quellcode sind die Hauptziele der Optimierung. - Die Dateien selbst
Last but not least – Die Dateien, die zusätzlich zum HTML Quellcode geladen werden müssen, sind in aller Regel die Schwergewichte und haben enorm große Auswirkungen auf die Ladezeiten. Klassische Fehler sind viel zu große Bilder, unbedacht eingesetzte JavaScript Bibliotheken oder massive Inline CSS Anweisungen im Quellcode. Es ist nicht unüblich, dass eine durchgängige Optimierung an diesen Parametern ca. 60% der Einsparungen der Ladezeit ausmacht.
Insgesamt lässt sich in den Optimierungen rund um die Seitenladezeiten festhalten, dass nicht eine zentrale Optimierung den Erfolg ausmacht, sondern das Zusammenspiel und die Einsparung an vielen kleinen Stellen sorgt im Endeffekt für den Turbo Boost Ihrer Webseite!
Weil in aller Regel Anpassungen an Server und Internetleitung nicht von SEO`s beeinflusst werden können, verzichten wir im Folgenden darauf und konzentrieren uns auf Tricks & Tipps bei der Optimierung der Ladezeiten bei den Details, die die Ladezeit sowohl direkt beeinflussen können und mehr oder weniger problemlos von SEO`s mit Zugriff auf HTML & PHP / ASP(.NET) optimiert werden können.
… und warum lädt meine Seite nun so langsam…?
Zu Anfang dieses Artikels habe ich etwas über den „Transportweg“ der Daten erklärt. Streng genommen hat der Transportweg an dem Ende, wo die Daten in den Browser eingespeist werden, eine kleine Pforte. Auch wenn die Leitung selbst eine schnelle Glasfaserleitung ist, können nicht alle Daten, die zeitgleich an der Browserpforte ankommen, auch hinein. Stellen Sie sich ein Kanalsystem vor – pro Kanal kann immer nur ein Element (technisch gesehen soundsoviel Kilobyte in einem Paket) durch einen Kanal geschickt werden. Stehen 5 Kanäle zur Verfügung, können 5 Elemente zur gleichen Zeit geladen werden. Die Übrigen müssen solang warten bis einer der Kanäle wieder frei ist. „Schwergewichte“ belegen dabei einen Kanal länger als kleinere Dateien, weil deren Größe mehr Pakete und „Versandeinheiten“ bedeuten.
Wie Sie an diesem Bild schon erkennen können ist eine schnelle Internetleitung damit allein nicht dafür verantwortlich, wenn die Ladezeiten von Webseiten zu langsam sind.
Optimierung der Ladezeit mithilfe von Anpassungen an den Daten selbst
Wie weiter oben schon erläutert stellen die Daten, die zur Anzeige auf dem Bildschirm benötigt werden, oft die Hauptlast an Datenvolumen dar. Wie Sie diese Daten optimieren können, zeigen wir Ihnen jetzt:
Bilder optimieren
Bilder sind oft aufgrund ihrer Dateigröße eine, wenn nicht die zentrale Datenlast. Werden viele Bilder geladen deren Dateigröße nicht hinsichtlich der Optimierung der Seitenladezeit bearbeitet wurden, entstehen in unserem Kanalsystem große Staus immer dann, wenn diese Bilder hindurch müssen.
Daher
- Nutzen Sie das Format JPEG für Fotos, da JPEG`s die höchste Komprimierungsstufe aufweisen und so das Datenvolumen natürlich begrenzen.
- Für Bilder mit wenig Farbtiefe eignen sich auch .GIF`s, die oft kleiner als JPEG`s sind. Aber sie verfügen auch nur über ein stark begrenztes Farbspektrum und eignen sich daher nicht als Dateiformat für Fotos im Allgemeinen
- Speichern Sie Bilder unter Photoshop oder GIMP stets mit dem Menübefehlt „Für Web und Geräte speichern“ ab, da dann schon unbenötigte Fragmente aus den Bilddateien entfernt werden mit dem Ergebnis, dass die Dateigröße insgesamt weiter abnimmt
- Beim abspeichern wählen sie zusätzlich eine Komprimierungsstufe (Qualitätsstufe), bei der es zu keiner bis wenig sichtbaren Qualitätseinbußen kommt. Wir selbst nutzen häufig 60% vom Original aus.
- Skalieren Sie Bilder nicht über den Quellcode – keiensfalls sollten Sie ein großes Bild (auch nicht komprimiert) in Ihre Webseite einbinden und es im Anschluß im Dokument selbst mit height & width Attributen des Tags herunterskalieren. Das anpassen und skalieren des Bildes erfordert Prozessorleistung (des PC`s) und lässt die Seite nicht schneller aufbauen. Zudem musste das große Bild schon durch den „Kanal“ hindurch und hat dort für genügend Stau gesorgt.
Für Videos gilt im Allgemeinen dasselbe – da die meisten Videos aber über Videoplattformen wie YouTube oder MyVideo per iFrame eingebettet werden, ist eine Optimierung der YouTube Ladezeiten beispielsweise nicht möglich – via iFrame eingebettete Inhalte sind physisch nicht Bestandteil des eigenen Quellcodes / der eigenen Seite sondern werden von extern (eben direkt vom YouTube Server) geladen. Ich verzichte daher hier auf weitere Optimierungsmaßnahmen – auf Nachfrage erstellen wir aber gern eine Analyse!
Optimierung der Ladezeiten mithilfe von JavaScripten
Erinnern Sie sich an das Kanalsystem – je größer die einzelnen Daten sind, umso länger dauert deren Transportweg durch den Kanal zum Browser hindurch. Dies gilt natürlich auch für JavaScripte und deren Bibliotheken, die in aller Regel über ein <script> Tag mit Pfadangabe komplett eingeladen werden – obwohl man häufig nicht gleich die ganze Bibliothek braucht, sondern nur einige wenige Zeilen. Daher
- Vermeiden Sie – wenn möglich – auf die Einbindung ganzer Bibliotheken!
- Versuchen Sie nur den Code zu erfassen, den Sie auch wirklich brauchen. Ich gebe zu, dass dieses Vorgehen immer dann problematisch wird, wenn Monate später neue Codefragmente hinzugefügt werden müssen. Das einmalige hinzufügen und ausnutzen ganzer Bibliotheken ist einfacher – aber es hilft eben nicht Ladezeit einzusparen!
- Fassen Sie ALLE JavaScripte in nur einer Datei zusammen! Als Ergebnis erhalten Sie eine mehr oder weniger große Datei, die einen Kanal länger belegt. Aber während sie EINEN Kanal blockiert, können weitere Elemente durch die verbleibenden freien Kanäle effizient und praktisch asynchron geladen werden.
- Zum Thema Asynchron: Überlegen Sie genau ob Sie JavaScripte unbedingt am Anfang des HTML Quellcodes brauchen – wenn die Funktionen erst bei der fertig geladenen Webseite benötigt werden, laden Sie die gesamte Datei erst am Ende der Seite um möglichst früh dem wartenden User erste Inhalte schicken zu können.
- In jedem Fall vermeiden Sie ausformuliertes JavaScript im Quelltext selbst! Zum einen gehören in den HTML Quelltext ausschließlich Inhalte und eben keine Funktionsbeschreibungen und zum anderen wird dieser Abschnitt auf jeder einzelnen Seite erneut geladen – weil er eben Bestandteil des HTML Quellcodes (meist sogar des Templates) ist. Rechnen Sie mal hoch: Nur 240 Zeichen jeweils auf 1.000 einzelnen Seiten im Template ausformuliert, macht 240.000 unnötig geladene Zeichen! Die Lösung steht weiter oben – alle JavaScripte gehören in eine externe Datei die dann per <script> Tag geladen wird. Trackingcodes bilden hier eine Ausnahme, die logischerweise ausformuliert auf jeder URL erreichbar sein müssen!
Optimierung der Seitenladezeit mithilfe von CSS
Generell wiederholen sich viele Erkenntnisse aus der Optimierung der Ladezeit mithilfe von JavaScripten, daher gehe ich nur kurz auf die einzelnen Maßnahmen ein:
- Fassen Sie alle CSS Dateien, die für dasselbe Medium zuständig sind, in eine zentrale CSS Datei zusammen! Häufig finden sich zusätzliche separate CSS Anweisungen für installierte Plugins oder gleich mehrere CSS Dateien zur Ausgabe am Monitor („medium=“screen“).
- Prüfen Sie regelmässig welche CSS Anweisungen nicht mehr gebraucht werden. Eine Webseite „wächst“ und mit ihr wachsen auch die Styleangaben die nicht mehr benötigt werden. Raus damit!
- Verzichten Sie vollständig auf Inline Styles! Häufig finden wir genau diese zuhauf in Webseiten die durch uns optimiert werden sollen. Inline Styles produzieren unnötige Datenlast und machen das System für Designänderungen / -anpassungen unflexibel und statisch.
- Achten Sie auf die Vererbungslehre“ CSS steht für „Cascading Style Sheets“ und „Cascading“ bedeutet nichts anderes als „kaskadierend“ – „vererbend“. Im Klartext heißt das, dass Angaben von übergeordneten Elementen auf die jeweils nachfolgenden vererbt und nicht nochmal wiederholt werden müssen. Jedes Zeichen hilft die Ladezeit zu verbessern!
Ladezeiten mit CSS Sprites verbessern
Nein – Sprites haben nichts mit dem beliebten Kaltgetränk der Kindheit zu tun. Ein Sprite fasst Hintergrundbilder zusammen und ermöglicht so das schnellere Laden dieser Daten. Weiter oben in diesem Text habe ich die Optimierung der Ladezeit mit einem Kanalsystem verglichen. Je mehr Kanäle durch Datentransfer belegt sind, umso länger müssen die übrigen Dateien der Webseite auf deren Transfer warten. Grundsätzlich ist es effizienter, wenn nur wenige große statt vieler kleiner Daten geladen werden müssen. Zwar ist dann ein Kanal länger belegt (weil größere Pakete – „Versandeinheiten“ hindurch müssen), aber in der Ladezeit der großen Datei können simultan weitere Daten über die übrigen Kanäle verteilt geladen werden.
Genau dieser Effekt wird durch das CSS Sprite ausgenutzt – statt vieler kleiner Hintergrundbilder wird eine große Bilddatei geladen, auf der alle benötigten Backgroundgrafiken enthalten sind. Zum besseren Verständnis anbei mal 3 Beispiele von nahmhaften Anbietern:
Die auf diesen CSS Sprites vertretenen Hintergrundbilder lassen sich einfach mittels CSS auf der Seite anzeigen, im Prinzip braucht man nur die beiden CSS Eigenschaften „background-image“ um die Anzeige eines Hintergrundbildes einzuleiten und „background-position“ um die richtige Hintergrundgrafik auf dem Sprite zu referenzieren und an der Stelle einzublenden, wo es schlussendlich hingehört. Das war`s!
Der Vorteil von CSS Sprites liegt auf der Hand – enorme Einsparung der Anzahl der zu ladenden Dateien. Der Nachteil ist ein deutlich höherer Aufwand in der Erstellung, Pflege und Wartung der Webseite, da die einzelnen Grafiken auf dem Sprite platziert und im Anschluss in der CSS pixelgenau referenziert werden müssen. Da dieser Aufwand aber in aller Regel einmalig ist, überwiegen die Vorteile einer schneller ladenden Webseite bei Weitem!
Die Kür der CSS & JavaScript Optimierung: Entfernung überflüssiger Leerzeichen, Kommentare und G-Zip Komprimierung
Wer sich bis jetzt durch den Artikel durchgearbeitet hat, besitzt strukturierte Meta Dokumente und einen schon halbwegs aufgeräumten Quellcode, der von technischer Perspektive das Laden und Verarbeiten der Elemente durch Webserver & Browser unterstützt. Aber innerhalb der geladenen Quellcodes warten nochmal neue Möglichkeiten der Optimierung. Diesesmal geht es ganz banal um
- Entfernung nicht benötigter Zeichen (Leerzeichen, Kommentarzeichen etc.)
- die Komprimierung der übriggebliebenen (benötigten) Zeichen
Das Entfernen unbenötigter Zeichen nennt man Minimierung (international „Minify“) und geschieht etwa wie folgt. Zuerst ein Beispiel ohne Minimierung:
div.menu {
background: black;
height: 15px;
width: 240px;
}
Nach der Minimierung sieht dieselbe Anweisung etwa wie folgt aus:
div.menu{background:#000;height:15px;width:240px}
Wie funktioniert das Minimieren von Dateien / Wie funktioniert minify?
Im Gegensatz zum ersten Beispiel oben wurden alle Leerzeichen entfernt. Auch die Zeilenumbrüche (gehören ebenfalls als Sonderzeichen zum Charset und benötigen Speicherplatz obwohl sie unsichtbar sind) sind im zweiten Beispiel entfernt worden. Im Wert des Background
Attributes wurde ebenfalls eingespart: Anstatt den Wert black
auszuschreiben, haben wir ihn mittels CSS Hex-Code auf „#000“ zusammengestaucht.
Was in unserenm Beispiel noch fehlt, aber in der Praxis immer und ständig vorkommt, sind doppelte Deklarationsblöcke. In großen CSS Datein verliert man schnell den Überblick und so fällt uns bei der Optimierung ständig auf, dass Klassen zugewiesene Werte an anderen Stellen wiederholt werden. Diese unnötigen Wiederholungen schrauben die Datenlast wieder nach oben, werden aber zur korrekten Anzeige am Bildschirm gar nicht benötigt (weil ja schon vorher deklariert).
Nach unserer Minimierung der CSS Datei ist das Ergebnis am Bildschirm komplett identisch, aber die geladene Datenlast hat sich nachweislich drastisch reduziert. Was in diesem Beispiel hier noch relativ harmlos erscheint, macht sich in großen Webseiten mit vielen CSS Eigenschaften allerdings ganz schnell enorm bemerkbar!
Wie funktioniert die Komprimierung
Vereinfacht ausgedrückt werden Daten komprimiert, indem ebenfalls Daten gelöscht werden. Besser: Sie werden ausgetauscht!
Ständig wiederkehrende Zeichen werden bei der Komprimierung durch Platzhalter ersetzt (stark vereinfacht ausgedrückt). Während die Minimierung also Redundanzen durch Löschung vermeidet, ersetzt die Komprimierung ganze Zeichenketten sofern sie immer und wieder im Dokument / Element vorkommen. Rein theoretisch kann ein Dokument auch manuell komprimiert werden – da aber kaum jemand seinen eigenen Quellcode derart detailliert und langfristig im Blick hat, macht dies keinen Sinn. Die Komprimierung wird auf dem Server ausgeführt und führt daher dort zunächst zu einem gewissen Rechenaufwand. Dieser Rechenaufwand lohnt sich aber in fast allen Fällen, denn die verkleinerte (komprimierte) Datei wird im Anschluß schneller durch das oben schon angeführte Kanalsystem geschleust.
Die gängigste Methode der Komprimierung ist das sog. „gzip“ – eine plattformunabhängige (im Sinne von Computersystemen) Kompression und völlig frei von irgendwelchen Patenten. GZip ist unter der GNU lizensiert und kann daher ohne Probleme auf Server – Betriebssystemen installiert und in Betrieb genommen werden. Dies ist sehr wahrscheinlich auch der Grund der weltweiten Verbreitung von GZip – aber das ist ein anderes Thema!
Wie lässt sich GZip anschalten / enablen?
Komprimiert wird auf dem Server, daher muss dieser angewiesen werden die Kompression auch tatsächlich vorzunehmen. Dazu gibt es zwei Möglichkeiten, die je nach Ihrem Server / Hosting in Betracht kommen. Die einfachste Möglichkeit ist die
- Mittels der .htaccess
IfModule mod_gzip
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
/IfModule
Wer das Modul „mod_gzip“ auf seinem Server aktiviert hat, kann diese sehr praktische und einfache Möglichkeit nutzen. Mit den oben skizzierten Zeilen wird dieses Modul angewiesen, die Dateiformate „.js“ (JavaScripte), „.css“ (Cascading Style Sheets), „.php“, generelle Textformate, „.html“ & „.xml“ zu komprimieren und künftig diese Daten nur noch komprimiert auszuliefern. An dieser Stelle sei vorgemerkt, dass nicht alle Dateiformate komprimiert werden sollten, denn beispielsweise „.jpg“ (oder equivalente Bildformate) Dateien sind bereits komprimiert und können nicht weiter verkleinert werden. Daher werden von der Kompression in der Zeile 8 auch die bildformate ausgeschlossen.Wer mit der oben aufgeführten Methode Schwierigkeiten hat, kann auch folgenden Code probieren:
IfModule mod_deflate.c
FilesMatch "\\.(js|css|html|xml)$"
SetOutputFilter DEFLATE
/FilesMatch
/IfModule
Wenn auch das nicht funktioniert, hat der gemietete Server / das eigene Hosting kein eingeschaltetes Komprimierungsmodul und man muss auf eine der folgenden Alternativen ausweichen. - Oder GZip Kompression mit PHP
php
ob_start("ob_gzhandler");
Dieser PHP Code gehört ganz oben in jedes PHP Dokument, welches „gezippt“ werden soll und weist den Server per PHP an, die Kompression einzuschalten und komprimiert auszuliefern. Im Gegensatz zur ersten Methode, GZip Kompression via .htaccess, hat diese Methode den Nachteil, dass sie in jede PHP Datei geschrieben werden muss. Darüberhinaus funktioniert sie auch nur bei PHP Dateien und der Programmierer muss jede gewünschte Dateiform zur Kompression durch PHP erzeugen. Daher sollte man die erste Version immer zuerst versuchen.
Tools rund um das Minimieren und Komprimieren von Daten
Minimieren und Komprimieren der Daten macht einfach hochgradig Sinn! Der Aufwand ist aber nicht zu unterschätzen – gerade das mühselige suchen von doppelten Deklarationen in den CSS Dateien ist an sich schon eine zeitraubende und fehleranfällige Angelegenheit. Google hat für diese Einsätze ein unglaublich wertvolles Tool auf den Markt gebrahct und bietet es kostenlos zum Download an: Google Minify.
Minify entfernt automatisch unnütze CSS Angaben oder JavaScript Daten, löscht Leerzeichen und Absätze aus denselben und liefert im Anschluss die bereinigten Datensätze GZip kodiert an den Browser aus. Für die wahren Technik Freaks das Sahnehäuptchen: Minify entfernt sogar unnötige Client-seitige Cache Header und setzt aktuelle Werte stattdessen ein. In eigenen Tests konnte Minify sogar dreiviertel an HTTP Requests einsparen – jene Anfragen an den Webserver, die unoptimiert einen Datenstau im Kanalnetz veranlassen.