Anzeige
Anzeige
UX & Design
Artikel merken

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.

Von Ilja Zaglov
3 Min. Lesezeit
Anzeige
Anzeige
t3n wünscht allen Codern einen fröhlichen Programmierertag 2013!

 

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

Anzeige
Anzeige

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:

Anzeige
Anzeige
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.

Anzeige
Anzeige

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.

Anzeige
Anzeige

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.

Anzeige
Anzeige
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.

Anzeige
Anzeige

Ü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.

Mehr zu diesem Thema
Fast fertig!

Bitte klicke auf den Link in der Bestätigungsmail, um deine Anmeldung abzuschließen.

Du willst noch weitere Infos zum Newsletter? Jetzt mehr erfahren

Anzeige
Anzeige
9 Kommentare
Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

Niklas

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
Niklas

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
Franky

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
Kris

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
Thomas Quensen

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
Ilja Zaglov

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
Martin Brüggemann

@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
SinnUndUnsinn

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
Christoph Jeschke

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
Abbrechen

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.

Bitte schalte deinen Adblocker für t3n.de aus!
Hallo und herzlich willkommen bei t3n!

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team von mehr als 75 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Schon jetzt und im Namen der gesamten t3n-Crew: vielen Dank für deine Unterstützung! 🙌

Deine t3n-Crew

Anleitung zur Deaktivierung
Artikel merken

Bitte melde dich an, um diesen Artikel in deiner persönlichen Merkliste auf t3n zu speichern.

Jetzt registrieren und merken

Du hast schon einen t3n-Account? Hier anmelden

oder
Auf Mastodon teilen

Gib die URL deiner Mastodon-Instanz ein, um den Artikel zu teilen.

Anzeige
Anzeige