Cachen ist das Zwischenspeichern von Dateien. Wenn eine Seite mit einem Bild bereits einmal geladen ist, wird das Bild zwischengespeichert. Warum soll der Browser beim erneuten Aufruf der Seite das Bild nochmals laden? Man spricht vom "Browser Cache".

Server nutzt Cache

Auf der anderen Seite steht der Server. Wird die Startseite von Joomla! angefordert, so holt Joomla! alle Informationen für die Startseite aus der Datenbank, presst Sie ins Template und liefert die so zusammengestellt Seite dar. Joomla! könnte die Seite, die gerade zusammengestellt wurde, so wie Sie ist auf der Serverseite in einem Verzeichnis als "statische" Seite ablegen. Beim erneuten Aufruf der Startseite, kann Joomla! dann auf diese Zwischengespeicherte - statische - Seite zurückgreifen und diese Ausliefern.

Das Cachen von Seiten erlaubt es demnach, Datenbankabfragen und das Ausführen verschiedenen PHP Skripte zu vermeiden, da der Server die Seiten als statische Datei ablegt und an den Browser ausliefert.

In Joomla! kann man den Cache im Backend in der Konfiguration einschalten.

Joomla! Cache aktivieren

Doch schauen Sie sich ihre Webseite nach Aktivierung des Caches nochmal an. Manche Erweiterungen laufen ggf. nicht mehr korrekt. Also: Testen, Testen, Testen.

Browsercache nutzen

Mit HTTP 1.1 wurde der "entity tag" (kurz ETag) eingeführt, der eine einfache Zeichenkette in Anführungszeichen ist. Laut Wikipedia besteht der ETag häufig aus der "systemspezifischen Inode, der Größe und dem Zeitpunkt der letzten Änderung der Datei". Alternativ nutzen einige den MD5 Hash der Datei selbst (siehe auch md5_file). Eine gute Abhandlung zum ETag finden Sie unter solariz.de. Folgendes Beispiel von php.net:

Wird das Feld im Header angegeben ...

<?php
  $file="mootools.js.php";
  // Inode
  $ETag = dechex(fileinode($file));
  // Size
  $ETag.= "-".dechex(filesize($file));
  // Modification time in useconds
  $ETag.= "-".dechex(((filemtime($file).str_repeat("0",6)+0) & (8589934591)));
  header("ETag: ".$ETag);
?>

... kann der Client beim nächsten Aufruf die ETag übergeben und damit den Server darauf hinweisen, dass er die Datei schon hat.

Bei der ersten Anfrage der mootools.js.php läuft folgende Kommuninkation:

Erste Anfrage ohne ETag in Antwort ETag enthalten

Die Anfrage (unterer Teil) zeigt die Anforderung vom Firefox. Die ETag ist ihm bisher nicht bekannt. In der Antwort (oberer Teil) übergibt der Server dem Firefox die Datei inkl. der ETag.

Die wiederholte Anfrage sieht dann wie folgt aus:

Weiter Anfrage mit ETag ohne Logik

Der Browser fordert die Datei "mootools.js.php" an (unterer Teil) und übergibt dem Server den ETag in der Zeile "If-None-Match". Der Server prüft und gibt dem Browser die Datei wieder komplett zurück inkl. der bereits bekannten ETag. D. h. wir haben hier zwar eine ETag drin, doch bringen wird es zur Zeit noch nichts.Wir basteln ein wenig weiter.

Greifen wir uns wieder die mootools.js.php und ergänzen folgende Zeilen:

...
  header("ETag: ".$ETag);

  if (trim($_SERVER['HTTP_IF_NONE_MATCH']) == $ETag) {
    header("HTTP/1.1 304 Not Modified");
    exit;
  }

  if( strpos( $_SERVER["HTTP_ACCEPT_ENCODING"],"gzip") !== FALSE){
    ob_start("ob_gzhandler");
  }
...

Ich lade die geänderte mootools.js.php hoch, lade die Seite ein erstes mal und dann noch einmal. Das Ergebnis zeigt die folgende Abbildung:

Weiter Anfrage mit ETag mit Logik

Durch das Skritp wird die ETag geprüft, die der Client sendet. Wenn die ETag noch übereinstimmt, muss die Datei nicht erneut gesendet werden. Die Meldung "304 Not Modified" wird übermittelt. Die Kommunikation wird abgeborhcne (exit()).

Wenn das nun in alle JavaScript und CSS-Dateien integriert wird, kommen wir zukünftig sehr schnell voran.

Weitere Infos zum Thema Cache

Artikel zum Thema Cache

  • Die ganze Wahrheit über Client-Caches (http://phpperformance.de/die-ganze-wahrheit-ueber-client-caches/)
  • HTTP 304 Not Modified (http://phpperformance.de/http-304-not-modified-performancesteigerung-kann-so-einfach-sein/)
  • Artikel "How to speed up your Joomla Web site with caching" auf The Art of Joomla

ETag für den Client Cache

  • Creating etag headers in php (http://www.htaccesselite.com/creating-etag-headers-php-vt112.html)
  • HTTP ETag, Nutzen und Funktionsweise (http://solariz.de/2044/etag_webseite_cache_caching_beschleunigen.htm)
  • php.net mit Beispielen zum ETag (http://php.net/manual/en/function.header.php)

Das folgende Skript lässt sich so für CSS- und JavaScript-Dateien einsetzen. Packt man alle Tipps der vorherigen Artikel zusammen, kommt dabei folgendes Heraus:

<?php

  header('Content-Type: text/javascript');

  $expires = 60*60*24*7;
  header("Pragma: public");
  header("Cache-Control: maxage=".$expires);
  header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');

  $files = array(
    "mootools.js",
    "caption.js"

  );

  $ETag = "";

  foreach ($files as $file) {
    $ETag = dechex(fileinode($file));
    $ETag.= "-".dechex(filesize($file));
    $ETag.= "-".dechex(((filemtime($file).str_repeat("0",6)+0) & (8589934591)));
    $ETag.="-";
  }
  $ETag= md5($ETag);
  header("Etag: $ETag");
  if (trim($_SERVER["HTTP_IF_NONE_MATCH"]) == $ETag) {
    header("HTTP/1.1 304 Not Modified");
    exit;
  }

  if( strpos($_SERVER["HTTP_ACCEPT_ENCODING"],"gzip") !== FALSE){
    ob_start("ob_gzhandler");
  } else {
    ob_start();
  }

  foreach ($files as $file) {
    include($file);
  }

  ob_end_flush();
?>

Das Script wird einfach ins Verzeichnis der JavaScripts (/media/system/js) z. B. unter dem Namen "js_together.php" kopiert. Anschließend werden wird dieses Skript in den Kopf der index.php des Templates eingebunden:

...
<head>

<script type="text/javascript" src="/media/system/js/js_together.php"></script>

<jdoc:include type="head" />
...

Es folgt die Betrachtung der Ladezeiten: Nach dem ersten Aufruf.

JavaScript - Zusammengepackt - Erster Aufruf

Die JavaScript-Dateien "mootools.js" und "caption.js" werden zusammen in der Datei "js_together.php" übertragen. Insgesamt sind das 20,7 KByte. Der Spaß dauert hier gerade mal 569 ms (Messung mit Firebug, von meinem Internetanschluss).

Der erneute Aufruf der Seite ...

JavaScript - Zusammengepackt - Weiterer Aufruf

... bewirkt, dass die Datei "js_together.php" nur die Meldung "304 Not Modified" zurückgibt. Das Ganze passiert in 192 ms. Wieder ein wenig Zeit gespart.

Das Ergebnis nach den Optimierungen aus "der perfekten Lösung für CSS- und JavaScript-Dateien":

Ergebnis first view

Ein großer Erfolg wir dann auch sofort beim erneuten Laden der Seite sichbar:

Ergebnis repeat view

Innerhalb von 1,4 Sekunden ist alles neu geladen. Nur fünf Bilder scheinen noch nicht gecached zu werden. Da muss man nochmal nachfassen.

Hier eine Sammlung weitere Tipps und Verweise

Content auf mehrere Server verteilen

Ein Artikel aus dem Yahoo! User Interface Block beschäftigt sich mit der Erhöhung der Geschwindigkeit, durch mehrere gleichzeitige Downloads, die vom Browser angestoßen werden.

Nach dem HTTP 1.1 Standard sind die gleichzeitigen Verbindungen auf zwei zu beschränken. Der Firefox nutzt ab der Version 3 sechs Verbindungen gleichzeitig pro Server.

Anzahl gleichzeitiger Verbindungen zu einem Server

Welcher Browser nutzt wie viele gleichzeitige Verbindungen zu einem Server (maximum persistent connections to server)?

Zitat Bugzilla: Firefox 2: zwei, Opera 9.26: vier, Safari 3.04 Mac / Windows: vier, IE 7: zwei, IE 8: sechs

In der Hilfe von Opera 9.02 findet man folgenden Text: "Bei Problemen mit der Internetgeschwindigkeit versuchen Sie die Anzahl der maximal gleichzeitigen Verbindungen zu verändern. Wir empfehlen Ihnen die Standardeinstellungen von 8 und 20 (pro Server / Insgesamt) nicht zu verändern, sollten keine Probleme auftreten. Testen Sie aber ruhig auch andere Einstellungen. Bei vielen DSL-Benutzern haben sich die Werte von z.B. 20 und 32 als optimal herausgestellt."

In der Hilfe zum Opera 10.50 liest man: "Max connections to a server: It is recommended to keep the default setting of 16, but you can try changing the maximum number of connections to a single server if you are experiencing problems with browsing speed."

Im Internet Explorer 8.0 Entwicklerbreich liest man: "Six connections per host for broadband scenarios instead of two, and a scriptable property, improve performance by allowing parallelization of downloads in Internet Explorer 8. This also increases functionality by ensuring that a request is not blocked to a host if two connections already exist. Websites can optimize downloads based on the window.maxConnectionsPerServer property.".

Und nochwas: Der Internet Explorer nutzt bei Breitbandverbindungen sechs, bei "Dial In" hingegen "nur" zwei Verbindungen gleichzeitig.

Fragen wie "Wie viele Verbindung sind zu viel?" oder "Wie viele Verbindungen sind OK, um die Performance zu verbessern?" - stellen sich hier. Erste Antwort: Das ist Server und Bandbreitenabhängig. Testen Sie selbst die für Sie optimalen Einstellungen. Beim Firefox und Opera lässt sich das schnell Einstsellen.

Um diese Eigenheit der Browser zu beeinflussen, kann man aus Betreibersicht, Inhalte auf mehrere Server verteilen. Z. B. lassen sich Bilder auf eine Subdomain legen: img.joomla-fulda.de oder auf Diensten wie flickr, myspace oder YouToube auslagern. So wird zwar eine zweite DNS Anfrage fällig, aber der Firefox würde nun mit 12 Verbindungen gleichzeitig saugen. Die Bandbreite muss natürlich auch zur Verfügung stehen.

Erhöhen der maximalen gleichzeitigen Verbindungen zu einem Server

Die Verteilung der Inhalte auf mehrere Server, ist ein Tipp zur Performanceverbesserung. Zwei Server / Domains sind wohl gut, mehr als vier verderben den Spaß wieder. Andererseits gibt es Berichte, die sogar mehr nutzen. Doch lesen Sie selbst ein wenig zum Thema "parallelize downloads across hostnames".

Viel Spaß dann beim Analysieren und Testen.

Verweise ins Web

Artikel zum Thema

  • Ladezeiten reduzieren (http://forum.jswelt.de/tutorials-php/38746-ladezeiten-html-webseiten-senken.html)
  • Yahoo - Best Practice To Speeding Up Your Web Site (http://developer.yahoo.com/performance/rules.html)
  • Schnellere Webseiten und höhere Conversion durch Komprimierung (http://www.alexander-langer.de/2009-03-30/ladezeiten-conversion-komprimierung.html)
  • Ladezeiten optimieren (http://webdesign.tepelmann.com/index_Ladezeit-Optimierung.html)
  • Hyper Text Transfer Protocol (http://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol)
  • Google - Optimize Browser rendering - Put CSS In Head (http://code.google.com/intl/de-DE/speed/page-speed/docs/rendering.html#PutCSSInHead)
  • Improving Drupal's page loading performance (http://wimleers.com/article/improving-drupals-page-loading-performance)
  • Galileo Computing - Joomla! Performance (http://openbook.galileocomputing.de/joomla15/joomla_35_performance_001.htm)
  • JavaScript und CSS-Dateien parallel Downloaden (http://phpperformance.de/javascript-und-css-dateien-parallel-downloaden/)

Tipps zum Thema Seitenoptimierung mit Google Analytics

  • http://www.askapache.com/javascript/google-analytics-speed-tips.html

Browservergleich - Maximum an gleichzeitigen Verbindungen pro Server

  • http://www.heise.de/ct/artikel/Surf-Triathlon-291708.html
  • http://stackoverflow.com/questions/561046/how-many-concurrent-ajax-xmlhttprequest-requests-are-allowed-in-popular-browser
  • http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/

Einfache Tests zum Thema "page load time"

  • http://www.webpagetest.org/ - Wie lange dauert es, bis Ihre Seite komplett geladen ist. Ladezeiten der einzelnen CSS, JavaSkrits und Bilder werden genauso angezeigt, wie der Komprimierungsgrad der einzelnen Dateien.
  • Firefox Erweiterugn "Firebug" ... dort unter Netzwerk die Funktionen aktivieren.
  • Firefox Erweiterung "lori (Life-of-request info)" zeigt, wie lange es dauert bis einen Seite geladen ist.

Webserver - Bin ich allein auf dem Server

  • http://www.yougetsignal.com/tools/web-sites-on-web-server/

Auf Webpagetest hat sich mittlerweile einiges getan. So kann man den Aufruf der eigenen Seite nun auch über mobile Endgeräte (iPAd, iPhone, usw.) über den Dienst "MoBiTest" testen lassen.

Webpagetest für mobile Endgeräte

Auch nett zu erfahren, wie es mit der Seite auf diesen Geräteklassen aussieht.

Analysieren wird Blaze.io

Das Ergebnis wird auch als Wasserfalldiagramm ausgegeben.

Blaze.io - Waterfall Diagramm

Mit "loads.in" bietet Unternehmen um Watchmouse (www.watchmouse.com) einen kurztest zum Analysieren der Ladezeiten an.

Mit Hilfe von loads.in Ladezeiten ermitteln

Man kann über mehr als 50 Server weltweit testen lassen. Auf JavaScript Fehler wird aufmerksam gemacht, doch wo welche Fehlere sind erkannt man nicht. Ein detailiertes Wasserfall-Diagramm zeigt, welche Dateien wie lange benötigt haben.

Mit Hilfe von loads.in Ladezeiten ermitteln

Für einen kurzen Test reicht es allemal aus. Alternative: www.webpagetest.org