Performance der Webseite optimieren

05.11.2010

Dieser Artikel beschreibt die Möglichkeiten, die Ihnen zur Verfügung stehen, um die Performance deutlich zu erhöhen. Es wird aufgezeigt, welche Auswirkung die Optimierungen haben und in welchem Fall diese überhaupt sinnvoll sind. 

Nicht jede Optimierung ist immer sinnvoll und nicht jeder Aufwand immer gerechtfertigt. Oft lassen sich allerdings enorme Performance-Verbesserungen bei geringem Aufwand erreichen und so Webserver, Netzwerke und Endgeräte entlasten.

Dieser Artikel betrachtet die folgenden drei Bereiche der Performance-Optimierung:

  1. Reduzierung der Skriptlaufzeit
  2. Reduzierung der Anfragen
  3. Reduzierung der zu übertragenden Datenmenge

Reduzierung der PHP Skriptlaufzeit

Hierbei handelt es sich um die grundlegendste und offensichtlichste Optimierungsmöglichkeit. Es geht darum, die generierten PHP-Seiten möglichst schnell auszuliefern und somit die Serverlast zu reduzieren. 

Diese Optimierungen führen zu grundsätzlich schnelleren Ladezeiten. Außerdem kann dadurch ggf. eine teurere Server-Hardware gespart werden.

Optimierungen und deren Auswirkungen auf einem Testsystem

Dieser Test soll Ihnen verdeutlichen, welche Auswirkungen die verschiedenen Optimierungen auf die Skriptlaufzeit einer beispielhaften Seite haben.

Eingesetztes System

  • Domainfactory myHome Basispaket ohne eAccelerator

Aufgerufene Seite:

  • 100 Navigationpunkte auf drei Navigationen verteilt
  • Liste mit 10 aus 1000 Einträgen
  • 10 skalierte Bilder
  • 3 eingebundene Inhaltsbereiche

Folgende Optimierungen wurden betrachtet:

  1. Optimierungen im Template
    - Attribut expires bei Navigationsaufrufen auf 1800 gesetzt
    - Attribut useIndex beim Einbinden von XSLT-Templates auf 1 gesetzt
    - nicht genutzte Elemente- und Objekt-Templates entfernt
  2. Einsatz des GRID Caches
    - Gültigkeit auf 1800 gesetzt
  3. Einsatz des GRID Caches mit Optimierung der pre.php Steuerungsdatei
    - Statt auf Variablen zuzugreifen, wurden Konstanten gesetzt.
Skriptlaufzeit pro Seitenaufruf in Millisekunden
Skriptlaufzeit pro Seitenaufruf in Millisekunden

Es zeigt sich, dass bereits wenige Optimierungen, welche die Aktualität einer Seite geringfügig beeinflussen deutliche Geschwindigkeitsvorteile bringen. 

Der GRID Cache ist dann notwendig, wenn eine sehr hohe Anzahl an Zugriffen stattfindet. In Kombination mit dem eAccelerator kann so die Skriptlaufzeit selbst bei einem leistungsschwachen Serversystem auf unter 3 Millisekunden reduziert werden. 

Je höher die Zugriffszahl, desto kürzer kann auch die Cache-Gültigkeit eingestellt werden, da das Verhältnis von statischen zu generierten Seitenaufrufen proportional zur Anzahl der Zugriffe pro Sekunde steigt. 

Neben dem klassichen GRID Cache können Sie auch bei Navigationen eine Gültigkeit über das Attribut expires angeben. Innerhalb dieses Gültigkeitszeitraums werden die Navigationen für nicht eingeloggte Benutzer gecached. Des Weiteren kann über das Attribut deep bei Navigationen definiert werden, wie viele Level zu berücksichtigen sind.

Falls Sie die Möglichkeit haben, den eAccelerator zu nutzen, erreichen Sie dadurch neben einer grundsätzlichen Beschleunigung der Skripte auch eine deutliche Reduzierung des Speicherverbrauchs.

Reduzierung der Anfragen

Bei der Reduzierung der Skriptlaufzeiten haben wir uns um die PHP-Dateien gekümmert. Pro PHP-Datei werden allerdings fasst immer mehrere Bilder, CSS und JavaScript Dateien ausgeliefert. Inzwischen kommt es nicht selten vor, dass Projekte neben den eigentlichen JavaScript-Dateien nochmal fünf oder mehr JQuery-Erweiterungen laden, um so mit allen Effekten gerüstet zu sein. Wenn dann noch eine Bildnavigation geladen wird, kommt man mit den Bildern der Seite und den CSS-Dateien schnell auf 30 Anfragen pro PHP-Seite. 

Auch wenn jede dieser Anfragen im Vergleich zu den PHP-Skripten praktisch keine Serverlast verursacht, so können diese in der Summe dennoch einen Webserver stark belasten. Natürlich gibt es die Möglichkeit, dynamische und statische Inhalte über getrennte Server auszuliefern, und diese auf die jeweiligen Anfragen zu optimieren. Grundsätzlich sollte allerdings angestrebt werden, die Anzahl der Anfragen zu reduzieren. 

Browser Cache nutzen

Wenn man bedenkt, dass sich CSS, JS und Bilddateien nur selten ändern, ist es nahe liegend, diese nicht bei jedem Seitenaufruf vom Browser laden zu lassen. 

Hierfür gibt es mehrere Ansätze:

1. Ansatz: Der Browser bekommt bei jeder Anfrage mitgeteilt, ob sich eine Datei geändert hat und ruft nur dann den Inhalt ab. Diese Variante reduziert die Übertragung bei jeder Anfrage deutlich, da nur eine Head-Anfrage gemacht werden muss. Allerdings reduziert sich die Anzahl der Anfragen nicht. 

2. Ansatz: Der Browser bekommt über das Apache Modul mod_expires im Header mitgeteilt, dass eine Datei bis zu einem in ferner Zukunft liegenden Datum gültig ist, und ruft diese auch erst erneut ab, wenn dieses Datum eingetroffen ist. Hierdurch wird die Anzahl der Anfragen enorm reduziert. Zwischenzeitlich gemachte Änderungen werden allerdings erst angezeigt, nachdem der Benutzer ein Neuladen erzwingt. Abhilfe ist möglich, indem der Dateiname einen Zeitstempel enthält, so dass bei jeder Änderung eine neue Datei ausgeliefert wird, die der Browser auf jeden Fall lädt.

3. Ansatz: Der Browser bekommt eine Gültigkeitsdauer von wenigen Minuten übermittelt, die mit 30 Minuten z.B. weit über der durchschnittlichen Besuchsdauer liegt, sodass die statischen Dateien pro Besuch nur einmal abgerufen werden müssen. Dieser Ansatz ist zwar nicht ganz so effizient wie Ansatz 2 mit Zeitstempel, führt allerdings bereits zu einer enormen Reduzierung der Anfragen und ist praktisch immer einsetzbar, weshalb er auch im Beispielprojekt so standardmäßig eingesetzt wird.

Weniger Dateien ausliefern

Allein die Anzahl der Anfragen hat einen Einfluss auf die Performance einer Webseite. Betrachten wir mal die benötigen JavaScript-Dateien, so gilt:

  • Ein kleines eingebettetes JavaScript ist besser als eine externe JavaSript-Datei
  • Eine große externe JavaScript-Datei ist besser als zwei mittlere externe JavaScript-Dateien.

Dass keine JavaScript-Dateien geladen werden müssen, ist relativ unwahrscheinlich. Es bietet sich deshalb an, die benötigten Dateien, seien es JavaScript-Dateien oder CSS-Dateien jeweils in einer einzigen Datei auszuliefern. Genau wie mehrere kleine Bilder über Sprites in einem einzigen Bild ausgeliefert werden, können Sie dies auch mit JavaScript- und CSS-Dateien machen.

Dazu müssen Sie lediglich das Attribut merge="1" setzen, damit alle registrierten JavaScript- bzw. CSS-Dateien zusammengeführt ausgeliefert werden.

Auslieferung nur einer JavaScript und CSS-Datei in zusammengeführter Form

<wsl:includeCssRessources merge="1" dirMerged="/wGlobalProject/wGlobal/layout/styles/merged" minimize="0"/>   
<wsl:includeJsRessources merge="1" dirMerged="/wGlobalProject/wGlobal/layout/scripts/merged" minimize="0"/> 

Reduzierung der zu übertragenden Datenmenge

Nachdem nun die Skripte schneller sind und nur noch wenige Dateien ausgeliefert werden, können Sie die Performance noch weiter optimieren, indem Sie generell weniger Inhalte übermitteln. 

  • Skripte werden, falls vom eingesetzten Browser unterstützt, bereits im Standard komprimiert ausgeliefert. 
  • JavaScript- und CSS-Dateien werden im Standardprojekt komprimiert ausgeliefert, sofern dies vom Webserver über das Apache-Modul mod_deflate unterstützt wird. 
  • Die Bildkomprimierung ist auf 80% Qualität voreingestellt und kann je nach Bedarf noch erhöht werden.

Allein diese Einstellungen reduzieren die Datenübertragung in der Praxis um bis zu 90%. Zusätzlich können die eingebundenen und über merge="1" zusammengeführten JavaScript- sowie CSS-Dateien über das Attribut minimize="1" auch noch zusätzlich minimiert werden, um die Datenübertragung nochmals geringfügig zu reduzieren.