Vorheriger Artikel Nächster Artikel

PHP-Projekte mit simplem Template Cache optimieren

Mit Caching kann viel Serverlast und damit auch Ladezeiten eingespart werden. Wir zeigen euch einen simplen Einsatz, der mit zunehmender Projektkomplexität viel Rechenleistung und Ladezeit ersparen kann.

PHP-Projekte mit simplem Template Cache optimieren

 

PHP Code - Foto: Bull3t, flickr.com. Lizenz: CC BY-SA 2.0

Heute zeige ich euch, wie ihr mit wenigen Codezeilen die Ladezeit eurer PHP-Scripte beschleunigen und die Serverlast verringern könnt, indem ihr einen simplen Template Cache in eure Scripte einbaut.

Wozu brauche ich einen Cache?

Wir gehen vom folgenden Szenario aus: Euer Script nutzt HTML-Templates mit festgelegten Sprachvariablen. Die Funktion hierfür könnte folgendermaßen aussehen:

function load_template($template_name){
	$path = "templates/".$template_name.".tpl";
	$handle = fopen ($path, "r");
	while (!feof($handle)) {
		$template .= fgets($handle);
	}
	fclose ($handle);
	$template =language_parser($template);
	return $template;
}

Bei jedem Aufruf von load_template() wird also ein html-Dokument eingelesen und anschließend an die Funktion language_parser() übergeben, in der die Verarbeitung der Variablen erfolgt. Diese Funktion ist bei einem einzelnen Aufruf harmlos. Aber: Je mehr Templates für die finale Ausgabe benötigt werden und je mehr Variablen diese enthalten, desto länger dauert das Parsen der Templates. Der Server wird zusätzlich belastet, die User müssen ggf. länger auf die aufgerufene Seite warten.

Stammen die Daten aus einer Datenbank, dauert der gesamte Vorgang noch länger. Kommt dann auch noch eine gewisse Menge Benutzer dazu, kann dies zu merkbaren Performance-Einbußen führen.

Die Lösung: Template Cache

Mit nur wenigen Codezeilen könnt ihr die Ladezeit in einem solchen Szenario deutlich verkürzen. Wir werden die Templates beim ersten Aufruf einlesen, die Variablen parsen und anschließend im System zwischenspeichern. Wird das Template erneut benötigt, laden wir es, ohne die Variablen erneut parsen zu müssen, direkt aus dem Dateisystem unseres Servers. Da die Templates nicht für immer so bleiben wie zum Zeitpunkt des Zwischenspeicherns, löschen wir sie nach einer festgelegten Zeit und legen sie erneut an.

Mit der folgenden Funktion legen wir die gecachte Version des Templates an.

function template_cache($template_name,$template_content="",$write=false){
	$cache_time = 18000;
	$path = "templates/cache/".$template_name.".tpl";
	if(!file_exists($path) or time()-filemtime($path)>=$cache_time){
		if(file_exists($path)){
			unlink($path);
		}
		if($write == true){
			$fh = fopen($path, 'w') or die("Öffnen nicht möglich: ".$template_name);
			fwrite($fh, $template_content);
			fclose($fh);
		}
	}
}

Die Funktion template_cache() erwartet drei Parameter: den Namen ($template_name), den geparsten Inhalt des Templates ($template_content) und die Anweisung das Template zu schreiben ($write). Anschließend überprüft das Script, ob die Datei bereits existiert und wenn ja, wie lange. Ist die Datei nicht vorhanden oder liegt der Timestamp, der von der Funktion filetime() zurückgegeben wird, zu weit in der Vergangenheit, wird die Datei gelöscht und falls $write auf true gesetzt wird, neu angelegt.

Nun müssen wir nur noch die load_template() Funktion anpassen.

function load_template($template_name){
	template_cache($template_name);
	if(file_exists("templates/cache/".$template_name.".tpl")){
		$path = "templates/cache/".$template_name.".tpl";
		$parse = false;
	} else {
		$path = "templates/".$template_name.".tpl";
		$parse = true;
	}
	$handle = fopen ($path, "r");
	while (!feof($handle)) {
		$template .= fgets($handle);
	}
	fclose ($handle);
	if($parse == true){
		$template=language_parser($template);
		template_cache($template_name,$template,true);
	}
	return $template;
}

Am Anfang der Funktion rufen wir template_cache() auf um zu überprüfen, ob die Datei, die ggf. bereits im Cache hinterlegt wurde, veraltet ist. Sollte das der Fall sein, wird sie von der Funktion gelöscht.  Andernfalls wird der Pfad ($path) zum Einlesen der Datei auf die gecachte Version und die Variable $parse auf false gesetzt. Das Script liest die gecachte Datei ein und überspringt das Verarbeiten und das erneute Speichern des Templates.

Sollte noch keine gecachte Version des Temples vorhanden sein oder die Datei veraltet sein, liest das Script das Ursprungstemplate ein, verarbeitet es mit language_parser() und legt das Template mit template_cache() in den Zwischenspeicher. Klingt einfach - ist es auch. Erspart aber bei entsprechendem Scriptumfang Rechen- und Wartezeit.

Template Cache: Kleiner Code, großer Effekt

Das hier beschriebene Beispiel ist ein sehr simpler Ansatz, der zeigen soll, wie man mit sehr wenig Einsatz und auch als Anfänger viel für die Performance seiner Scripte tun kann – ohne auf große Frameworks oder Kompilierung der Scripte zurückgreifen zu müssen. Es ist nur ein Ansatz von vielen, wie euer Projekt effizienter werden kann und hat erst ab einer gewissen Besucherlast und Komplexität des Projektes einen stark spürbaren Effekt. Ein nützlicher und ausbaufähiger Helfer ist es jedoch allemal.

Über den Autor

Ilja big

Ilja Zaglov ist selbstständiger Kommunikations- & Mediendesigner. Er unterstützt kleine und mittelständische Unternehmen bei der Erstellung von Online- und Offline-Medien. Neben Web-Gestaltung gehören Motion-Graphics und 3D-Inhalte zu seinen Spezialgebieten.

NEU: Lass dir diesen Artikel vorlesen
Ein Service von t3n, in Kooperation mit Narando.
Vorheriger Artikel Zurück zur Startseite Nächster Artikel
9 Antworten
  1. von Niklas am 29.11.2012 (16:27 Uhr)

    Guter und hilfreicher Ansatz. Die Komprimierung der Dateien via htaccess ist eine weitere (simple) Maßnahme um noch einige kb einzusparen. Dazu braucht man nur folgende Zeilen in die .htaccess eintragen:

    # compress text, html, javascript, css, xml:

    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript

    Antworten Teilen
  2. von Niklas am 29.11.2012 (16:34 Uhr)

    Mist, jetzt hats die Tags mit spitzen Klammern entfernt. Nach dem Kommentar muss noch:
    IfModule mod_deflate.c

    und nach der letzten Zeile:
    /IfModule

    beides in spitzen Klammern natürlich. Sorry für den doppelten Kommentar :/

    Antworten Teilen
  3. von Franky am 29.11.2012 (17:30 Uhr)

    Nicht vergessen sollte man ebenfalls den eTag und ein paar zusätzliche Cache-Headers. Hier ein paar Beispiele dazu: http://blog.franky.ws/php-und-das-caching-via-http-header-etag/

    Antworten Teilen
  4. von Kris am 29.11.2012 (17:43 Uhr)

    Es geht in dem Eintrag rein weg um die Minimierung der Rechenleistung von PHP.
    Franky und Niklas schreiben von der serverseitigen Bereitstellung der Daten.

    Als Beispiel:
    Wenn das PHP Script 1 Sekunde benötigt um ein Template zu verarbeiten, wird das Caching an dieser Stelle schnell sinnvoll.
    Die generierte Datei wird einfach ausgegeben und das Script selbst braucht die Daten nicht neu zu verarbeiten.

    Im Gegenzug ist die Größe der gecachten Datei (ohne Änderungen) gleich groß.

    Die serverseitigen Optimierungen machen Sinn, haben aber mit dem Template caching meines Erachtens nichts zu tun.

    Antworten Teilen
  5. von Thomas Quensen am 29.11.2012 (17:53 Uhr)

    Was bei dem Beispiel nicht berücksichtigt wird, ist die Tatsache, dass Templates in aller Regel dynamische Elemente/Variablen/Platzhalter enthalten, die sich bei verschiedenen Aufrufen unterscheiden und somit nicht einfach beim ersten Aufruf gecacht werden dürfen.

    Daher macht die gezeigte Version nur Sinn, wenn die Templates keine Variablen enthalten, oder für jede verschiedene Variablenkombination eine eigene Datei angelegt wird, was allerdings sehr viel Speicher fressen könnte bei tausenden verschiedener Möglichkeiten)

    Sinnvoller anwendungszweck wäre hier nur das Umwandeln einer "fremden" Templatesprache in PHP-Code, der danach dann einfach included werden kann - allerdings kann man sich diesen Schritt auch komplett sparen, da PHP problemlos direkt als Template-Sprache verwendet werden kann.

    Antworten Teilen
  6. von Ilja Zaglov am 29.11.2012 (18:08 Uhr)

    Ich verwende den Ansatz in erweiterter Form. Die Sprachvariablen und andere, sich selten ändernde Elemente werden für den Cache geparst, die dynamischen Inhalte dann wiederum noch mal mit PHP erzeugt.

    Antworten Teilen
  7. von Martin Brüggemann am 30.11.2012 (09:18 Uhr)

    @Thomas Nach Möglichkeit am besten gar kein PHP in den Templates verwenden, sondern irgendeine Template-Abstraktionsschicht wie Twig oder Fluid. Dann kann man auch mal einen Designer direkt in den Templates arbeiten lassen und das Caching/Cache-Expiration gibts meist gratis dazu. PHP in Templates ist 90er ;) (aber manchmal leider noch nötig).

    Antworten Teilen
  8. von SinnUndUnsinn am 30.11.2012 (17:37 Uhr)

    Der Quelltext ist 90er "or die" fopen/fwrite usw.
    Wie gesagt die View schicht darf auch auf das Model zugreifen.
    Warum darf kein php Quelltext in die View?
    Daraus ist php entstanden.
    Schau dir z.b. mal das Zendframework an.

    Caching ist am performantesten in einer Schicht zwischen
    Model und Controller / Model und View (Service oder Mapper) halt....

    Antworten Teilen
  9. von Christoph Jeschke am 01.12.2012 (22:34 Uhr)

    Der Quelltext ist nicht nur "90er", sondern auch noch anfällig für Race Conditions: Zwischen den file_exists-Prüfungen und der tatsächlichen Payload (unlink, fwrite, etc.) kann es passieren, dass ein anderer Prozess die soeben geprüfte Bedingung obsolet macht. Besser wäre es, mit temporären Dateien und atomaren Funktionen zu arbeiten.

    Davon abgesehen sollte man das Rad nicht ständig neu erfinden. Nahezu jedes Framework bringt Caching mit.

    Antworten Teilen
Deine Meinung

Bitte melde dich an!

Du musst angemeldet sein, um einen Kommentar schreiben zu können.

Jetzt anmelden

Mehr zum Thema Templates
Joomla: 15 schicke Templates für deine Webseite
Joomla: 15 schicke Templates für deine Webseite

Mit Templates kannst du das Aussehen von Joomla steuern. Wir stellen dir 15 kostenlose und kostenpflichtige responsive Templates für den Einsatz mit Joomla zur Inspiration vor. » weiterlesen

HAML macht HTML kompakter, übersichtlicher und bringt mehr Struktur
HAML macht HTML kompakter, übersichtlicher und bringt mehr Struktur

Mit HAML kannst du HTML-Templates mit deutlich weniger Code anlegen und so eine bessere Übersicht im Vergleich zu konventionellen Template Engines herstellen. Wir verraten, wie HAML funktioniert. » weiterlesen

Tempy.js: Blitzschnelle Client-Templates mit HTML5-LocalStorage
Tempy.js: Blitzschnelle Client-Templates mit HTML5-LocalStorage

Es gibt viele verschiedene Möglichkeiten zur Realisierung von Client-Side-Templates. Tempy.js nutzt den LocalStorage, um die Aufrufe zu minimieren und die Performance zu steigern. Wir stellen es … » weiterlesen

Kennst Du schon unser t3n Magazin?

t3n 38 jetzt kostenfrei probelesen! Alle Inhalte des t3n Magazins Diesen Hinweis verbergen