Das ganz normale Chaos, täglich frisch auf den Tisch. Direkt aus der hintersten Provinz in die Metropolen von Groß-Blogistan.


Schnell-Seiten

Tue, 13 Apr 2010 13:14:00 +0200

Seit Google die Ladegeschwindigkeit einer Seite dadurch geadelt hat, dass dieser Faktor einer von 200 Ranking-Faktoren ist, überschlägt sich das Internet beinahe mit Anleitungen dazu, wie man seine Seite schneller macht. Ich befürchte, da wird a) mal wieder das Kind mit dem Bade ausgeschüttet und b) der Blick auf andere wichtige Dinge vernachlässigt. Nicht, dass ich Geschwindigkeit für vernachlässigbar oder gar überflüssig halte. Dass eine schnelle Seite angenehm zu bedienen ist, da stimme ich mit Christian Schäfer absolut überein. Geschwindigkeit ist ein Usability-Faktor.

Aber wie Alles im Leben hat auch dies seine zwei Seiten. Schon vor längerer Zeit entstand bei Yahoo eine Art Richtlinie oder Checkliste, anhand derer man seine Seiten schneller machen konnte oder sollte. Um die zwei Seiten zu beleuchten, werde ich daher mal jeden dieser 14 Punkte aufführen und kommentieren. Die Punkte sind dabei, wie bei Yahoo, nach Priorität (Wirkung) absteigend sortiert. Das heisst, der erste Punkt hat die größte Auswirkung, der letzte die geringste.

  1. Anzahl HTTP-Requests (= Datei-Requests) minimieren

    Eine Seite, so, wie wir sie am Bildschirm sehen, ist nicht nur eine einzelne Datei. Die Seite zu laden bedeutet also nicht, eine einzelne Datei zu laden. Um die Seite anzuzeigen, müssen viele Dateien geladen werden. So ist z.B. jedes Bild eine einzelne separate Datei. Auch Stylesheets und Scripte können in separaten Dateien liegen. Es macht einen Unterschied, ob ich Alles in eine Datei packe (sofern das denn geht), oder ob ich das Alles auf viele verschiedene Dateien verteile. Denn der Faktor Geschwindigkeit wird nicht allein durch die Übertragung der Daten bestimmt. Für jede einzelne Datei muss eine Verbindung zunächst auf- und danach wieder abgebaut werden. Das kostet Zeit. Offensichtlich um so mehr Zeit, je öfter eine Verbindung auf- und abgebaut werden muss. Von daher würde es also Sinn machen, alle Styles und Scripte mit in die html-Datei zu integrieren. Es gibt aber gute Argumente, die dagegen sprechen. So ist z.B. eine modular aufgebaute Seite erheblich besser wartbar. Dazu kommen Cache-Effekte: Wenn ein separates Stylesheet bereits geladen wurde, muss es bei der nächsten Seite nicht noch mal geladen werden. Der zusätzliche Zeitaufwand bei der ersten Seite spart also bei jeder folgenden Seite wieder Zeit ein. Wenn die Site also aus mehr als einer Seite besteht, lohnt es sich, die Styles in eine separate Datei zu packen, auch, wenn das den Ladevorgang für die erste Seite verlängert.

    Dazu kommt ein weiterer Aspekt, der bei Google allerdings, so weit ich das sehe, keine Rolle spielt. Für die gefühlte Geschwindigkeit kommt es nämlich überhaupt nicht auf die Zeit an, bis auch das letzte Byte geladen ist. Für die gefühlte Geschwindigkeit ist die Zeit ausschlaggebend, die verstreicht, bis ich die Seite nutzen kann. Dieser Timer startet allerdings jedes Mal neu, wenn die Seite so reformatiert wird, dass ich den momentanen Lesepunkt verliere. Grob gesagt, ist die gefühlte Ladezeit die Zeit, die verstreicht vom ersten Klick bis dahin, wo der Text der Seite lesbar ist und in der endgültigen Geometrie dargestellt wird. Bis zu diesem Zeitpunkt müssen noch keine Bilder geladen sein, es sei denn, diese Bilder sind essentielle Inhalte der Seite. Reine Dekorationen sind hier für die Zeitmessung irrelevant.

  2. Ein Content Delivery Network verwenden

    Dies ist ein Faktor, den Betreiber kleinerer Sites getrost vernachlässigen können. Solch ein Content Delivery Network ist nur was für die Giganten im Web.

  3. Dateien mit längeren Verfallsdaten ausstatten

    Hier kommt der Cache ins Spiel. Und, wie bei Punkt 1 bereits angeführt, kann man dafür sorgen, dass bestimmte Dateien ab der zweiten Seite eben nicht mehr aus dem Web geladen werden müssen (womit sowohl die Zeit für Auf- und Abbau der Verbindung entfällt als auch die Übertragungszeit), sondern von der lokalen Platte. Klar, ein Blogartikel eignet sich nicht dazu, lange gespeichert zu werden. Da können oft und kurzfristig Änderungen anstehen. Aber das trifft nur auf den eigentlichen Inhalt des Artikels zu. Stylesheets und Dekorationen werden sich so schnell nicht ändern. Diesen Dateien kann man ein in ferner Zukunft liegendes Verfallsdatum spendieren. Damit muss selbst bei einer graphisch opulenten Seite nur noch der eigentliche Inhalt aus dem Web geladen werden. All die viele Dekoration liegt bereits auf der Platte des Clients vor. Jedenfalls nach dem ersten Besuch. Natürlich setzt das voraus, dass man auch, wie von w3c empfohlen, Inhalt und Dekoration sauber getrennt hat.

    Achtung: Dynamisch (z.B. via PHP) erzeugte Dateien können grundsätzlich überhaupt nicht zwischengespeichert werden. Diese dynamisch erzeugten Dateien haben immer eine Verfallszeit von Null (verfällt sofort).

    Zur Aktivierung und Kontrolle dieses Verfallsdatums gibt es bei Apache das mod_expires. Die entsprechenden Informationen kann man problemlos für jedes Verzeichnis separat in eine .htaccess schreiben.

  4. Daten komprimiert verschicken

    Dieser Punkt ist heute in Zeiten großer Übertragungsgeschwindigkeiten nicht mehr ganz so wichtig. Aber einen gewissen Effekt hat das natürlich immer noch. Um Dateien komprimiert zu verschicken, kann man, sofern vorhanden, das mod_deflate einsetzen. Wenn es nicht vorhanden ist, kann man die Dateien auch manuell zippen (mit gzip), und den Apache Server mit Hilfe des mod_negotiation automatisch eine der beiden Versionen wählen lassen. So habe ich das hier gemacht, da dieser Webspace eben kein mod_deflate bietet. Zum Glück ist mod_negotiation per Default vorhanden.

  5. Stylesheets in den Quelltext-Kopfbereich

    Da bin ich eher dagegen. Stylesheets gehören aus den bereits angeführten Gründen in separate Dateien. Aber das Einbinden dieser Stylesheets sollte in der Tat im Kopfbereich der html-Datei erfolgen. Denn nur so kann gewährleistet werden, dass die Seite von Anfang an zumindest in der korrekten Geometrie dargestellt wird. Dadurch wird die Seite bereits nutzbar, bevor die ganze Dekoration geladen ist. Aufpassen muss man hier bei farbigen Hintergründen. Angenommen, die Webseite soll nach Laden sämtlicher Dekoration weissen Text auf schwarzem Hintergrund zeigen. Was zeigt die Seite dann nach Laden des Stylesheets, aber vor dem Laden der Dekoration? Weissen Text auf weissem Hintergrund. Das ist natürlich nicht nutzbar. Es sei denn, man hat nicht vergessen, im Stylesheet den Hintergrund auf schwarz zu setzen. Egal, ob dieser schwarze Hintergrund später komplett von der schwarzen Dekoration verdeckt wird.

  6. JavaScripts in den Quelltext-Fußbereich

    Dadurch wird die Seite zunächst mal sinnvoll dargestellt (sofern das ohne Javascript möglich ist, worauf man tunlichst achten sollte). Die ganzen dynamischen Extras der Seite können warten, bis der Rest geladen ist.

    Nur in einem Punkt möchte ich hier konkretisieren: Das Javascript gehört nicht inline in die html-Datei, sondern in eine externe Datei. Die Gründe dafür habe ich oben aufgeführt.

  7. Keine Internet Explorer Expressions in Stylesheets verwenden

    Nun, das lässt sich oft genug nicht vermeiden. Aber man kann diese Microsoft Sonder-Spezialitäten in eigene Stylesheets auslagern, und das Einbinden dieser Stylesheets über Conditional Comments auf den IE beschränken. Damit wird die Seite im IE langsamer, aber in richtigen Browsern bleibt sie schnell.

  8. Stylesheets und JavaScripts nicht einbetten, sondern in Dateien auslagern

    Amen!

  9. Maßvoll viele DNS-Anfragen erzeugen

    Wie macht man das? Und warum? Das Warum ist recht schnell erklärt: Aus den selben Gründen, aus denen man auch die Anzahl der http-Requests minimiert. Zwar kommen DNS-Anfragen ohne Verbindung aus, aber die Anfrage muss trotzdem raus, und die Antwort abgewartet werden. Auch DNS-Anfragen sind zwischenspeicherbar. Das macht der Browser von sich aus, darum muss man sich nicht weiter kümmern.

    Aber wie minimiert man denn nun diese Anfragen? Ganz einfach, indem man möglichst alle Dateien von nur einem Host lädt. Das ergibt dann eine Anfrage, und gut ist. Gravatare oder Scripte von anderen Hosts benötigen jeweils eine weitere DNS Anfrage. Je weniger solcher Anfragen es gibt, um so besser.

    Für besonders häufig besuchte Seiten, oder für Seiten, bei denen man ein klein Wenig extra Sicherheit benötigt, kann man diese Informationen auch manuell in eine lokale Datei schreiben. Unter Unix ist das /etc/hosts. Unter Windows liegt diese Datei irgendwo unter \windows\system32. Der Vorteil: Angreifer können diese Information nicht so einfach fälschen. Nachteil: Wenn die Adresse sich ändern sollte, muss man manuell nachbessern.

  10. JavaScript minifizieren (CSS aber auch)

    Nun ja, das ist heute dank schneller Datenübertragung nicht mehr so wichtig. und wenn Kompression vorhanden ist, gar nicht mehr. Aber es kann sehr nützlich sein, wenn man seine Dateien auf andere Art schlank hält: Ein logischer Aufbau der Styles und Scripte spart nicht nur viel überflüssigen Mist, sondern erleichtert auch die Wartung dieser Dateien. Hier sind allerdings nicht mechanische Tools gefragt, sondern ordentliche und saubere Konzepte.

  11. Umleitungen vermeiden

    Warum? Nun, jede Umleitung erfordert einen weiteren http-Request.

  12. Doppelungen/Redundanzen bei den JavaScripts vermeiden

    Nicht nur da. Doppelungen und Redundanzen benötigen immer Zusatzaufwand.

  13. ETag abschalten

    Dagegen! Ein ETag ist ein Hilfsmittel, mit dem ein Browser feststellen kann, ob er eine Datei neu laden muss, oder ob sie sich seit dem letzten Laden nicht geändert hat. Das Bisschen, was man durch das Weglassen des ETags gewinnt, ist es nicht wert, diesen Vorteil zu verlieren.

  14. AJAX-Anfragen cachen

    Wie das? Nun ja, wenn die Antwortdateien statisch vorliegen, kein Problem. Was aber, wenn diese Antworten dynamisch erzeugt werden, per PHP aus einer Datenbank? Dann braucht man PHP, um das dennoch zu ermöglichen. Und vielleicht ETags. Aber ab hier wird es dann aufwendig.

Alles in Allem kann man sehen, dass etliche Anforderungen sich gegenseitig widersprechen. Andererseits kann man davon ausgehen, dass ein sauberer modularer Aufbau zusammen mit einer guten Cache-Strategie sehr viel Geschwindigkeit bringen können.

Und zum Schluss noch eine Anmerkung: Ich finde es ziemlich blödsinnig, jede noch so statische Seite dynamisch aus einer Datenbank zu erzeugen. Das ist auch ein Grund, warum ich heute real existierende Content Management Systeme nicht gut finde. Dynamisch generierte Seiten können nicht zwischengespeichert werden. Sie verfallen sofort. Selbst, wenn sie sich in 100 Jahren nicht ändern, verfallen diese Seiten sofort. Und warum das Ganze? Keine Ahnung. Man könnte problemlos Content Management Systeme entwickeln, die die Seiten nicht in einer Datenbank ablegen, sondern in html-Dateien. Das kann kann von mir aus eine Exportfunktion sein, so dass die bearbeitbare Version weiterhin in der Datenbank bleibt. Aber die Dateien, die der Server ausliefert, sollten statisch ausgeliefert werden, sofern ihre Natur statisch ist.


0 Kommentare