performance css javascriptJavaScript und CSS befinden sich heute auf praktisch jeder Webseite. Bei beidem kann man allerdings aus Performance-sicht so einiges falsch machen. Deshalb möchte ich zusammenfassen, wie man die Performance von JavaScript- und CSS-Code optimieren kann und dadurch den Seitenaufbau beschleunigen kann.
Diesen Blogpost werde ich in die folgenden Teile zerlegen:

  1. Browserabhängiges CSS
  2. JavaScript- und CSS-Dateien zusammenführen
  3. JavaScript- und CSS minimieren
  4. optimaler Ort/Reihenfolge zum Referenzieren von JavaScript und CSS

Browserabhängiges CSS

Dass CSS nicht von allen Browsern einheitlich interpretiert wird ist bekannt. Speziell der IE6 macht häufig was er will. Deshalb setzen Webentwickler häufig sogenannte Browserweichen ein.

#nav {left: 157px;}
body > #nav {left: 117px;}

Die obere Regel wird von allen Browsern verwendet. Die zweite Regel wird von allen Browsern außer dem IE verwendet, weil dieser den Selektor: > nicht kennt. Deshalb werden alle “nicht IE-Browser” die zweite Regel, und der IE die erste Regel verwenden. Diese gängige Praxis ist aus Performance-sicht nicht optimal, weil zum einen die CSS-Datei durch “Doppelregeln” unnötig groß wird und zum anderen mehr CSS-Regeln vom Browser verarbeitet werden müssen.
Um das Problem zu lösen wandel ich meine CSS-Datei in eine PHP-Datei um1 und kann dadurch PHP innerhalb des CSS verwenden. Der folgende Code-Schnipsel löst das Problem von oben:


JavaScript- und CSS-Dateien zusammenführen

Jede Datei, die zum Anzeigen einer Webseite notwendig ist muss (vereinfacht gesagt2) einzeln vom Server angefordert werden. Ziel dieser Optimierung ist die Reduzierung der HTTP-Requests, d.h. die Anzahl der Anfragen an den Server zu minimieren. So sieht der HEAD-Bereich einer typischerweisen Webseite aus:






Es werden also N einzelne CSS-Dateien für die Darstellung benötigt. Der folgende PHP-Code1 kann in eine CSS-Sammel-Datei geschrieben werden. Dadurch werden die Inhalte aller CSS-Dateien hintereinander in die neue CSS-Sammel-Datei geschrieben.


Diese CSS-Sammel-Datei wird ganz normal im HTML referenziert:




Die zu übertragende Datenmenge hat sich dabei nicht verändert. Es verringert sich nur die Anzahl der HTTP-Requests, wodurch die Seite wesentlich schneller läd. Kleiner Nebeneffekt: Je länger eine Datei ist, desto effizienter funktionert die Komprimierung. In einigen Sonderfällen sollte man auf die Zusammenführung verzichten: wird auf einer Unterseite nur eine sehr kleine CSS-Datei benötigt und auf einer anderen Unterseite mehrere sehr große, so bietet es sich an die CSS-Dateien nicht zusammenzuführen.
JavaScript-Dateien lassen sich genauso zusammenfügen. Dabei muss nur der Content-Type von “text/css” in “text/javascript” geändert werden.

JavaScript- und CSS minimieren

Bei dieser Optimierung geht es darum Zeichen aus der JavaScript bzw. CSS-Datei zu löschen, die für die funktionalität ohne Bedeutung sind. Im Internet existieren bereits etliche kostenlose CSS- und JavaScript minifier (z.B. CSSTidy oder cssdrive.com), die vollautomatisch ihre Arbeit erledigen. Die Qualität (Kompressionsrate) ist dabei meist sehr gut. Wer sein CSS / JavaScript allerdings häufig ändert wünscht sich vermutlich eine etwas komfortablere Variante. Der folgende PHP-Code komprimiert eine CSS-Datei zur Laufzeit (“on the fly”):

  ob_start('compress');

  function compress($data)
    {
    $data = str_replace(array("n","r","t",": "),array("","","",":"),$data);
    $data = str_replace("'","",$data);
    $data = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $data);
    $data = preg_replace("/;( *)}( *)/i","}",$data);
    $data = preg_replace("/ *{ */i","{",$data);
    $data = preg_replace("/; */i",";",$data);
    $data = preg_replace("/ *, */i",",",$data);
    return $data
    }

Da der PHP-Befehl preg_replace wie jeder Befehl, der reguläre Ausdrücke verwendet, äußerst langsam ist, ist ein Cachesystem für die Ergebnisdatei pflicht!
Für JavaScript gibt es ähnliche Codeschnipsel im Internet. Bei meinen Tests gab es allerdings kein Script, dass alle von mir getesten JavaScripts fehlerfrei verkleinern konnte. Deshalb möchte ich auch keine Empfehlung aussprechen – Probiert einfach einige aus!

Optimaler Ort und Reihenfolge zum Referenzieren von JavaScript und CSS

Es gibt eine einfache Faustregel: CSS so weit oben wie möglich im Quellcode stehen – ideal wenn alles was mit CSS zutun hat im head-Bereich steht. Dadurch kann der Browser bereits mit dem Seitenaufbau beginnen, obwohl noch nicht die ganze Seite heruntergeladen wurde.
Bei JavaScript ist es ganau andersrum: JavaScript sollte soweit wie möglich unten im Quellcode stehen – idealerweise kurz vor dem . Die Ursache dafür ist, dass JavaScript den HTML-Baum ändern kann und das natürlich nur Sinn macht, wenn der HTML-Baum auch vollständig bekannt ist.
Sollten in head-bereich mehrere CSS- und JavaScript-Dateien vorhanden sein, die nicht zusammengeführt werden können, so sollten diese streng nach typ sortiert werden: erst alle CSS-Dateien und dann alle JavaScript-Dateien. Der Grund hierfür liegt darin, dass der Browser gleiche Dateitypen parallel downloaden kann und beim wechsel von JavaScript und CSS jeweils warten muss, bis die erste Datei fertig runtergeladen wurde.
Das HTML-Attribut defer gibt dem Browser einen Hinweis, dass das JavaScript keine Inhalte in die Seite einfügt. Dadurch können nachfolgende CSS-Dateien parallel zur JavaScript-Datei heruntergeladen werden. Verfügbar ist das HTML-Attribut defer breits im Internet Explorer und seit Version 3.1 auch im Firefox.



1= damit alle Browser PHP-Dateien, die CSS enthalten auch als CSS-Datei anerkennen, muss der richtige Content-Type gesetzt werden (z.B. mit PHP: header(‘content-type: text/css’); )
2= die echte Anzahl der Dateien, die gleichzeitig geladen werden können, ist von Browser und Betriebssystem des Nutzers abhängig.