Schnelle Seiten

Sehr sehr schnelle Seiten – Website Performance Best Practice

 

Website Performance ist ein sehr weitläufiges Thema und erstreckt sich über nahezu alle Aspekte der Webentwicklung. So ist es auf der Serverseite möglich, mit cleverem Caching von dynamisch generiertem Markup, dem Optimieren und Reduzieren von Datenbankabfragen und dem Setzen der wichtigen Expires undCache-Control Header sehr schnell möglich, einen hohen Grad anPerformance zu erreichen. Auf der Clientseite hingegen finden sehr häufig die meisten Geschwindigkeitsverluste statt.

 

Die folgende Liste erhebt keinen Anspruch auf Vollständigkeit, sondern stellt vielmehr eine Auswahl von clientseitigen Optimierungsmöglichkeiten dar, die grundsätzlich jeder Webseite gut tun und einfach zu implementieren sind:

 

HTTP-Abfragen reduzieren

 

Dies ist die allgemeinste Regel dieser Liste und gleichzeitig auch die Wichtigste. Im gesamten Ablauf des Ladens einer Webseite sind die HTTP-Abfragen die grössten Bremsen, die dankbarer Weise aber auch am Einfachsten zu beheben sind. Viele der folgenden Regeln beziehen sich hierauf. Bei einer HTTP-Abfrage geht viel Zeit verloren, weil beispielsweise die Headerinformationen bei der Anforderung jeder einzelnen Datei vom Client an den Server geschickt werden und auch wieder zurückgeliefert werden. Dies sind teure Bytes, die hier von meist redundanten Datenpaketen verschwendet werden. Eine noch viel deutlichere Verzögerung sind die Latenzzeiten der Webserver, die – bevor sie die Anfrage verarbeiten können – erst einmal reagieren müssen. Je nach Belastung des Servers und der Entfernung zum Client kann sich dies bis zu mehreren wertvollen Sekunden hinziehen.

 

Optimierung des HTMLs

 

Eine HTML Seite enthält nur HTML

 

CSS oder Javascript haben inline in der HTML Seite nichts verloren. In der Regel sind diese in externen Dateien viel besser aufgehoben, da sie sie dort vom Browser gecached werden und somit ohne Performanceverlust von der gesamten Website genutzt werden können ohne immer wieder neu geladen werden zu müssen.

 

Der Inhalt zuerst

 

Die Reihenfolge der Elemente im Markup bestimmt Ihre Wichtigkeit und den Zeitpunkt wann sie vom Nutzer wahrgenommen werden können. Banner oder externe Widgets werden naturgemäß langsamer geladen als der Inhalt der Seite, der sie einbindet. Daher sollten sie idealerweise auch erst nach dem Inhalt im Markupreferenziert werden. Es fühlt sich für den Nutzer subjektiv schneller an, den Inhalt der Seite zu sehen und auf die Banner oder Widgets zu warten als umgekehrt.

 

Optimierungen für Bilddateien

 

Das richtige Dateiformat

 

Für Photografien und Grafiken mit sehr großem Farbumfang wie z.B. ein Verlauf ist JPEG die erste Wahl. Für Grafiken mit einer geringeren Anzahl von Farben empfiehlt es sich, dem 8 bit PNG dem Vorzug vor dem Klassiker GIF zu geben, da das PNG effektiver komprimiert und dadurch fast immer in der kleineren Datei resultiert.

 

Bilddateien auf das Wesentliche reduzieren

 

Nahezu jedes Grafikprogramm schreibt Informationen über sich selbst und das Bild in die Datei. Während diese Informationen bei der Bearbeitung durchaus sinnvoll sein können, stellen Sie bei der Darstellung im Internet meist nur unnötigen Ballast dar. Hilfsprogramme wie pngcrush oder der Webservice smush.it entfernen diese ungenutzten Bits und reduzieren so effektiv Downloadzeit.

 

Alphatransparenzen meiden

 

Im Gegensatz zum Rendern herkömmlicher opaker Grafiken muss der BrowserGrafiken mit Alphatransparenzen sehr häufig neu berechnen, um die entstehenden Mischungen korrekt wiedergeben zu können. Dies strapaziert den Browser und damit das Betriebssystem mit erhöhter Prozessorlast und grösserem Arbeitsspeicherverbrauch, was wiederum in hässlichem Ruckeln bei Animationen oder beim Scrollen resultieren kann.

 

Sprites reduzieren HTTP-Requests

 

Eine sehr effektive Technik um HTTP-Requests zu reduzieren, ist aus vielen kleinen Bildern ein Großes zu machen. Dies ist ausschließlich bei CSS-Hintergrundbildern sinnvoll, da nur diese über das „background-position“-Attribut das Anzeigen eines Bildausschnittes ermöglichen. Es empfiehlt sich, Bilder zu Sprites zu kombinieren, die inhaltlich und farblich zueinander passen, um ein intelligentes Caching zu ermöglichen und die Farbpaletten klein zu halten. Der CSS Sprite Generator z.B. kann dies bequem automatisieren und auch noch direkt das notwendige CSS generieren.

 

Bilder nie im HTML skalieren

 

Man sollte nicht glauben, daß ich dies hier erwähnen muss, aber zu große Bilder, die im HTML kleiner skaliert werden, sind mit die beliebtesten Performance-Bremsen überhaupt. Leider sind dem Entwickler hier häufig die Hände gebunden da diese Sünde meist von unwissenden Content Management System Nutzern begangen wird. Hier hilft nur Nachsitzen und lernen.

 

Optimierungen für CSS

 

CSS wird im <head> verlinkt

 

Neben dem Inhalt ist das Grunddesign eines der wichtigsten Seitenbestandteile, die dem Nutzer fehlen, wenn sie nicht sofort sichtbar sind. Um dies zu erreichen, muss das CSS im <head> mit dem <link> Element eingebunden sein. Wird das CSS nicht im <head> sondern im <body> verlinkt oder es wird nicht das <link> Element sondern @import zur Einbindung genutzt, kann dies zum unschönen „Flash of unstyled Content (FOUC)“, einem Aufblitzen des unformatierten Inhalts, führen.

 

CSS wird kleiner mit Shorthands

 

Viele CSS-Eigenschaften können auf verschiedene Arten geschrieben werden. Auch wenn es übersichtlicher ist z.B. die verschiedenen Hintergrundeigenschaften einzeln Zeile für Zeile zu definieren, so ist es mit Blick auf die Dateigrößesinnvoller, die Eigenschaften in Ihrer Kurzform zusammenzufassen.

 

So wird z.B. aus:

body{
background-color:#000000;
background-attachment:fixed;
background-image:url(pic.png);
background-position:left;
background-repeat:no-repeat;
}

folgende Kurzform:

body{background:#000 fixed url(pic.png) left no-repeat}

 

Minifizierung für maximale Geschwindigkeit

 

Deutlich verkleinert werden können CSS-Dateien durch das Anwenden spezieller CSS-Kompressor-Applikationen wie z.B. CSS Tidy oder YUI Compressor. Diese können den CSS-Code auf verschiedene Arten optimieren. Die einfachste Methode ist das Entfernen von unnötigen Leerzeichen und Zeilenumbrüchen. Zusätzlich können aber auch noch fortgeschrittene Techniken wie z.B. das automatische Zusammenfassen von redundanten Eigenschaften und das Kombinieren von Anweisungen in deren Kurzform angewandt werden.

 

Kombination reduziert HTTP-Requests

 

Das Aufteilen der Styles in mehrere logisch getrennte und strukturierte CSS-Dateien ist während des Entwicklungsprozess unerlässlich. Sobald die Seite live ist, sind die resultierenden zusätzlichen HTTP-Requests jedoch in der Regel einPerformanceproblem. Ein einfaches Kombinieren der einzelnen Dateien in der richtigen Reihenfolge behebt diesen Makel sehr einfach. In Ausnahmefällen von mehreren sehr großen Stylesheets kann das parallele Laden einzelner Dateien denPerformanceverlust der vermehrten HTTP-Requests wieder ausgleichen und zu einem schnelleren Endergebnis führen. Hier gilt es (wie immer) durch Testen zum bestmöglichen Ergebnis zu kommen.

 

CSS-Expressions vermeiden

 

Nicht während des Ladens sondern während der Benutzung einer Webseite stellen sich CSS-Expressions als Geschwindigkeitssünder heraus. Der Internet Explorer führt diese in CSS eingebetteten Javascriptanweisungen nämlich nicht nur dann aus, wenn es sinnvoll wäre, sondern bei absolut jeder Gelegenheit. Dies wirkt sich insbesondere dann negativ aus, wenn man die CPU für andere rechenintensive Operationen gut brauchen könnte wie z.B. für Animationen.

 

Optimierungen für Javascript

 

Javascript als letzes vor </body>

 

Eine noch relativ junge Erkenntnis ist, daß ein externes Javascript, bis es komplett geladen und vom Browser verarbeitet ist, den gesamten weiteren parallelen Lade- und Renderprozess des Browsers stoppt. Dies führt zu unnötigem Zeitverlust im Aufbau des Inhalts und des Designs. Um dies zu vermeiden, müssen alle externen Javascriptdateien als letztes Element vor dem abschließenden </body>-Tageingebunden werden.

 

Minifizierung – was für CSS gut ist kann für Javascript nicht schlecht sein

 

Auch bei Javascript kann durch die Benutzung von Applikationen wie z.B. JSMinoder YUI Compressor sehr viel Dateigröße eingespart werden. Um dies ohne unerwünschte Fehlermeldungen zu überstehen sollte Javascript schon während der Entwicklung unbedingt ständig mit JSLint auf mögliche Probleme geprüft und somit auf eine bestmögliche Kompression vorbereitet werden.

 

Auch Javascript in Kombination schneller

 

Das Kombinieren aller externen Javascriptdateien reduziert die Anzahl der HTTP-Requests und sorgt damit für einen schnellen Download. Ed Eliot stellt einkomfortables PHP-Script zur Verfügung, das nicht nur das automatische Kombinieren von CSS- und Javascriptdateien ermöglicht, sondern auch noch gleichzeitig eine optionale JSMin-Optimierung anwenden kann.

 

Javascript mehrstufig zünden

 

Ebenso wichtig wie die effektiven Downloadzeiten ist die subjektiv wahrgenommene Geschwindigkeit, in der sich eine Webseite aufbaut. Insbesondere bei komplexeren Javascript-Applikationen kann es notwendig sein, dem Nutzer die notwendige Lade- und Initialisierungszeit subjektiv zu verkürzen. Dies kann durch einen mehrstufigen Aufbau erfolgen. Da das Javascript aus Performancegründen zuletzt geladen wird, ist es ein erster Schritt, diese Lücke mit einem positiven Feedback an den Nutzer zu schließen. Der folgende Javascript-Einzeiler eingebunden im <head> der Seite kann CSS frühzeitig über das Vorhandensein von Javascript informieren und somit das Aussehen der Webseite entsprechen anpassen, auch wenn die eigentliche Applikation noch läd:

 

<script type="text/javascript">document.documentElement.className += ” js”;</script>

 

ermöglicht ein spezielles Javascript-Design im CSS durch Benutzung der .js Klasse

#mein-javascript-modul{/* Design ohne Javascript hier */}

.js #mein-javascript-modul{/* Design mit Javascript hier */}

 

Nicht auf window.onload warten

 

Eine der wichtigsten Entwicklungen, um Javascript schneller Ausführen zu können, ist der onDomReady() Event. Während der Klassiker window.onload() wartet bis die gesamte Seite inklusive aller externen Dateien und Bildern geladen ist ermöglicht uns onDomReady() Javascript gegen die Seite auszuführen sobald der DOM-Baum verfügbar ist und sorgt so für einen sehr großen Geschwindigkeitszugewinn.

 

Nach dem Laden ist vor dem Laden

 

Ist die erste Seite geladen, kann mit Javascript direkt weitergedacht werden. Wenn Elemente wie z.B. große Sprites auf den folgenden Seiten benötigt werden ist dies der Zeitpunkt, um diese bequem für den Nutzer vorzuladen, sodass die nächsten Seiten der Website eine zusätzliche Beschleunigung erfahren können.

 

Schnelleres Javascript durch Event Delegation

 

Je größer die Anzahl von Javascript-Events in einer Webseite, desto träger verhält sich diese bei der Benutzung. Ein sehr effektiver Weg, die Anzahl der Events gering zu halten, ohne Funktionalität einzubüßen ist Event Delegation. Hierbei wird davon profitiert, dass Javascript-Events sich automatisch im DOM nach oben bewegen (bubbling) und sich dadurch zwangsläufig an dem obersten gemeinsamen Knoten (z.B. <body>) treffen. Anstatt also wie gewohnt jedem Element dass z.B. auf einen Klick reagieren soll einen eigenen onclick()-Handler zuzuweisen, macht man dies statt dessen nur einmal an dem obersten gemeinsamen Knoten und prüft dort, von welchem Kindknoten der Event ursprünglich ausgelöst wurde.

 

Generelle Optimierungen der externen Dateien

 

Komprimieren, wenn möglich

 

Eine kleine Einstellung in den Webserverkonfigurationen bringt einen grossen Vorteil: gzip. Einmal in z.B. Apache aktiviert, liefert der Server Dateien komprimiert und damit durchschnittlich über 70% kleiner an kompatible Browser aus. Ein unschätzbarer Vorteil, der häufig ungenutzt bleibt.

 

Browser Caches vollständig nutzen

 

Statische Dateien sollten so lange gecached werden wie möglich. Dies kann ebenfalls z.B. für Apache mit dem Header ExpiresDefault "access plus 10 years" erreicht werden. Zu beachten ist hierbei aber, dass bei Aktualisierungen der gecachten Dateien eine Dateinamensänderung notwendig wird, um die neue Version sichtbar zu machen. So wird z.B. aus „logo.png“ die Datei „logo1.png“ wenn sie sich geändert hat oder aus „layout1.css“ wird „layout2.css“.

 

Nicht auf der gleichen Domain wie die Cookies ablegen

 

Der Browser schickt alle Cookies der aktuellen Domain bei jedem einzelnen Aufruf jeder Datei automatisch mit. Je nach Größe des Cookies ist dies ein signifikater Datentransfer, der z.B. bei einem Bild vollkommen unnötig ist. Um dies zu vermeiden macht es Sinn, alle statischen Dateien auf einer anderen Domain abzulegen, als die Inhaltsseiten. Nutzt man die „www“-Subdomain, reicht schon eine paralleleSubdomain wie zum beispiel „statisch.meineseite.de“. Nutzt man hingegen die top-level Domain „meineseite.de“, werden automatisch alle Cookies auch an alleSubdomains geschickt. In diesem Fall sollte über die Verwendung einer zweitenDomain nachgedacht werden.

 

Mehrere Domains für statische Dateien

 

Ein weiterer Vorteil des Zugriffs auf die statischen Dateien über andere Domains ist eine alte Beschränkung von HTTP/1.1. Hier wurde definiert, dass Browser immer nur zwei Dateien parallel von einer Domain laden sollen. Zu Modemzeiten war dies auch sicherlich eine gute Idee. Heutzutage können wir diese Beschränkung einfach mit der Nutzung von mehreren Subdomains aushebeln. Nutzt man „statisch1.meineseite.de“ und „statisch2.meineseite.de“ abwechselnd als Pfad beispielsweise zu Bildern, kann der Browser schlagartig vier anstatt nur zwei Bilder gleichzeitig laden. Dies macht allerdings nur bis zu ca. vier parallelen Domainseinen Vorteil aus, da jede Domain gleichzeitig auch einen zusätzlichen DNS-Lookupvoraussetzt, der selbst wieder eine Verzögerung darstellt.

 

(Quelle: webkrauts.de – Autor: Dirk Ginader)