Ladezeiten von (HTML-)Webseiten senken

jeko

Lounge-Member
Hallo zusammen,

Hier soll eine kleine Zusammenstellung von Methoden zur Verbesserung der Performance und Ladezeiten einer mit PHP generierten HTML-Seite erfolgen.
Ergänzungen sehr erwünscht!


Einleitend

Um die Ladezeiten einer Seite zu senken, gibt es mehrere Ansätze. Die Festlegung von Zielen und einer Strategie spielt nun eine zentrale Rolle, denn ohne Ziel kein Weg. Zunächst einmal sollten die Faktoren, welche die Ladezeit beeinflussen, spezifiziert werden. Bei einer herkömmlichen Webseite dürften diese (sehr grob) folgende sein:
  • Menge der Daten die zwischen Server und Browser transportiert werden
  • Bearbeitung durch den Server
Damit wissen wir auch was unsere groben Ziele sind:
  • Reduzierung der Datenmengen
  • Optimieren der Bearbeitungszeit des Servers
Behält man sich diese etwas im Hinterkopf auch während des Arbeitens an der Webseite, spart man sich auch später wenn's ums Optimieren geht viel Ärger.
Nun aber die konkreten Massnahmen.


HTML-Code komprimieren

Im Sinne von "Reduzierung der Datenmengen" kann man den HTML-Code, den man zum Browser schickt, komprimieren. Benutzt man PHP, kann man die Kompression ganz leicht mit ob_start() aktivieren. Dabei wird jede Ausgabe, die während des Scripts gemacht wird, in den Ausgabepuffer geschrieben und zuletzt komprimiert und gesendet.
Der PHP-Code dazu:
PHP:
<?php
// Puffer aktivieren
ob_start("ob_gzhandler"); // Die Komprimierung hier ist gzip
?>
Die Kompression ist vor allem bei HTML-Code sehr effektiv und kann je nach Grösse des Codes erhebliche Unterschiede in der Ladezeit hervorrufen.

Anmerkung: Der komprimierte Code muss vom Browser wieder extrahiert werden können. Nicht jeder Browser unterstützt diese Option, weswegen es sich empfiehlt dies erst einmal zu überprüfen. Was der Browser akzeptiert, teilt er uns im HTTP_ACCEPT_ENCODING-Header mit, den man wie folgt auslesen und zum Beispiel auf gzip-Kompatibilität prüfen kann:
PHP:
// Der Header den wir auslesen, kann zum Beispiel so aussehen:
// Accept-Encoding gzip,deflate
// Wir überprüfen also im folgenden, ob die Zeichenkette "gzip" im Header enthalten ist (was bedeutet, dass der Browser diese Komprimierung unterstützt)
if(strpos(@getenv("HTTP_ACCEPT_ENCODING"),"gzip") !== FALSE) {
        ob_start("ob_gzhandler");
}


Anzahl der Objekte reduzieren

Wird eine HTML-Seite geladen, wird jedes Objekt das im Code angegeben mit einem separaten HTTP-Request vom Browser geladen. Das heisst, jedes Bild, jede CSS-Datei, jede JavaScript-Datei, etc. werden mit einem einzelnen Request geladen.
Das Senden und Empfangen eines Requests braucht Zeit, die auch auf Kosten der Ladezeit geht. Daher sollte man versuchen, die Anzahl solcher Objekte zu reduzieren. Vor allem Bilder wo sie nicht nötig sind und Dateien die gar nicht für den Seitenaufbau und die Funktionalität der aktuellen Seite benötigt werden.
Sollte man verschiedene CSS-/JS-Dateien laden müssen, lohnt sich die Überlegung, ob man diese nicht zusammenfassen kann.
Ein Beispiel:
Geladen werden müssen
menu.css für's Menü (20 Zeilen), logo.css (5 Zeilen), mainstyle.css (120 Zeilen).
Das wären 3 Requests allein für das CSS. Die Überlegung wäre nun, dass man vor allem Stylesheets die auf jeder Seite gebraucht werden, zu einer zusammenfasst. Man kopiert den Inhalt der menu.css, logo.css und mainstyle.css in eine Datei: menu_logo_mainstyle.css.
Wir haben uns damit 2 Requests eingespart.


Javascript komprimieren

Auch Javascript lässt sich komprimieren. Sollten vor allem auch grössere Scripts oder Bibliotheken geladen werden, lohnt es sich ab einer gewissen Grösse auch über eine Komprimierung nachzudenken.
Die Komprimierung von der ich hier spreche, ist eher eine Schlankungskur für JS-Code. Dabei werden unnötige Leerzeichen, Umbrüche, Kommentare, und lange Variablennamen weggekürzt und führen so zu einer geringeren Dateigrösse, und somit zu weniger Ladezeit. Da die Arbeit manuell sehr aufwändig werden kann, gibt's dafür auch Tools, die ziemlich effektiv arbeiten und teilweise 60% oder mehr Komprimierungsraten herausholen.
Online:
JavaScript Compression - Compress JavaScript Code Free with this JavaScript Compressor (CSS Too) - from Creativyst
Javascript Compressor

Offline als App: js-builder - Google Code


Zugriffe auf externe Datenquellen reduzieren & optimieren

Auch hier gilt: Weniger ist mehr. Jeder Zugriff auf eine Datenquelle ausserhalb von PHP braucht Zeit. Darunter fallen vor allem Datenbankzugriffe, Dateizugriffe, Zugriffe auf Daten auf anderen Servern etc. Daher sollte man diese Aufrufe versuchen effektiv zu gestalten und die Aufrufe gesamt reduzieren und im Einzelnen zu optimieren. Ein weiterer Aspekt auch in der Datenmenge (nicht Anzahl Quellen): Nur abfragen, was abgefragt werden muss.
Können mehrere SQL-Queries auch zu einem zusammengefasst werden, wieso nicht? Sollte es die Übersicht des Code nicht stören und ist man einigermassen bewandert in SQL, lohnt sich das zusammenfassen von mehrere einzelnen Queries auf jeden Fall.
Weiter auch in der Datenmenge. Man sollte sich fragen, welche Daten man überhaupt aus der Quelle braucht. Vor allem im Datenbankbereich ist SELECT * eine Todsünde. Denn auch hier werden Daten übertragen, und wo Daten übertragen werden müssen, braucht's Zeit. Was bringt es also, alle Spalten einer Tabelle auszulesen (*) wenn nur der Name des Users gefragt ist? Nichts, ausser, dass wir den User etwas länger auf die Seite warten lassen, als nötig ist.


PHP: Programmiertechnische "Tricks"
PHP ist im Vergleich zu anderen Interpretersprachen dank der guten Einbettung sehr schnell. Trotzdem lässt sich noch einiges herausholen mit kleinen Tricks beim Programmieren. Viele der folgenden Tipps können auch auf andere Sprachen übernommen werden.
  • Funktionen, die in PHP schon eingebaut sind, sollten eigenen vorgezogen werden (sofern beide das gleiche machen);
    1. muss das Rad nicht immer neu erfunden werden, 2. sind diese meist nativ in PHP einprogrammiert und somit viel schneller in der Ausführung
    PHP:
    // Die folgende Funktion zählt die Elemente eines Arrays.
    // Die eingebaute Funktion count() von PHP erledigt das Gleiche und schneller
    function countElements($arr) {
    	$i = 0;
    	foreach($arr as $value) $i++;
    	return $i;
    }
    $foo = array('aha','soso','3 elemente, oder?');
    echo countElements($foo)."\n"; // 3
    echo count($foo)."\n"; // 3
  • Ergebnisse wenn sie mehrmals benötigt werden in einer Variable ablegen
    Jede Operation braucht Zeit; sollte die Länge eines Strings mehr als einmal im Script gebraucht werden, könnte man sie auch temporär speichern; Das Ergebnis einer Rechnung sowieso.
    PHP:
    // Der String "12345678900987654321" soll in der Mitte geteilt werden
    $string = '12345678900987654321';
    $teil1 = substr($string,0,strlen($string)/2);
    $teil2 = substr($string,strlen($string)/2);
    
    // Obiges kann sehr viel schneller, und auch übersichtlicher so gelöst werden
    $string = '12345678900987654321';
    $mitte = strlen($string)/2;
    $teil1 = substr($string,0,$mitte);
    $teil2 = substr($string,$mitte);
    Auch ein Schleifenkopf kann zu einem Resourcenfresser werden, wenn in der Abbruchbedingung eine Operation bei jedem Durchgang berechnet wird. Besser ist es, sollte die Operation immer den gleichen Wert ergeben, diesen abzuspeichern:
    PHP:
    // Gutes Beispiel: Array durchlaufen
    
    // Auf den ersten Blick ok...
    $i = 0;
    $arr = array('hello','world','...'); // Der Effekt zeigt sich vor allem bei grösseren Arrays mit mehreren 100 Einträgen
    for ($i=0; $i < count($arr) ;$i++) {
    	// ....
    }
    
    // Aber besser:
    $i = 0;
    $arr = array('hello','world','...');
    $len = count($arr);
    for ($i=0; $i < $len ;$i++) {
    	// ....
    }
    Schleifen sind tückische Speicherfallen, da sie ziemlich unscheinbar daherkommen (mit ein paar Zeilen Code), aber sehr mächtig sein können. Jede Schleife sollte genau überprüft werden, auf unnötige Operationen, die vielleicht im Vorfeld schon erledigt werden könnten. Sie werden sonst für jeden Durchgang von neuem ausgeführt.

    Allgemein gilt: Jede gesparte Operation, ist gesparte Zeit. Empfohlen jedoch nur bei gleich bleibender Funktionalität und gewahrter Übersicht.
[Fortsetzung folgt...]
 
Zuletzt bearbeitet:
Zurück
Oben