Kann man XSL als richtiges Templatesystem verwenden? Diese Frage stellte sich mir, nachdem ich vor einigen Tagen erst in der Vorlesung davor hörte und mich danach näher damit beschäftigte. Und: Wenn man es kann, ist es dann effizienter oder gar ganz schlecht perfomant gegenüber ein normales PHP-Script oder ein Smarty-Pendant?
Um zu testen, wie es sich mit der Performance verhält, stellte ich kleines Szenario auf: Der hauptsächliche Teil besteht daraus, und 1000 Einträge mit den Ausprägungen Name, E-Mail, ICQ, Website, etc. aufzustellen. Dabei ist Name einer von 3 unterschiedlichen, damit man eine bedingte Anzeige im Template realisieren kann.
PHP der Ameisenklasse:
class DataStressTest
{
private static $if = null;
public static function init( $if )
{
self::$if = $if;
self::stress();
}
private static function stress()
{
$sections = array(
array(
'header'=>'Gummibärchen',
'content'=>'..'
),
array(
'header'=>'Autobahnwahn',
'content'=>'..'
),
array(
'header'=>'Copy for Dummys',
'content'=>'..'
)
);
$websites = array(
'www.microsoft.com',
'www.google.com',
'pentagon.mil',
'web.de',
'gmx.de',
'ask.com',
'knallisworld.de'
);
$results = array();
$names = array('John','Mary','James');
for($i=0;$i<1000;$i++) = array(
'id' => mt_rand(1,1000),
'name'=>$names[array_rand($names)],
'mail'=>'john@wayne.de'.mt_rand(1,1000),
'icq'=>mt_rand(1000,10000),
'hobby'=>'schnucken',
'homepage'=>$websites[array_rand($websites)]
);
}
//assignment
self::$if->assign('sections', $sections);
self::$if->assign('members', $results);
self::$if->assign('title', 'Performance Stress Test by knalli');
}
}
Varianten
Szenario 1: Normales PHP-Template
Es wird ganz regulär eine PHP-Datei per Include eingebunden, die ausnahmslos nur Platzhalter und Ausgabelogik enthält. Das bedeutet, es befinden sich in der Regel nur for/foreach, if und echo Konstrukte. Zusätzlich können besondere Ausgabefunktionen eingebunden werden, wie zB utf8_encode().
Szenario 2: Smarty-Template
Es wird ein entsprechendes Smarty-Template genutzt; das generierte Template seitens Smarty entspricht so grob dem Szenario 1.
Szenario 3: XML-Generierung und XSL-Processing
Zunächst wird mit DOMDocument von PHP5 das DatenXML aufgebaut; wir sehen später noch, das DOMDocument::createElement die Hauptarbeit machen wird. Anschließend geschieht das Processing.
Die Ergebnisse
Mittels Advanced PHP Debugger loggte ich alle Varianten mit. Die übliche Methode, mit PHP::microtime() die Sekunden zu zählen, bringt weniger Informationen über die echte Laufzeit und zeigt keine Informationen über die internen Laufzeiten.
Szenario 1: Normales PHP-Template
Total Elapsed Time = 1.54 Total System Time = 0.13 Total User Time = 0.50
Szenario 2: Smarty-Template
Total Elapsed Time = 1.85 Total System Time = 0.17 Total User Time = 0.59
Szenario 3: XML-Generierung und XSL-Processing
Total Elapsed Time = 4.71 Total System Time = 0.40 Total User Time = 1.36
Nun, dieses Ergebnis war niederschmetternd. Während die Differenz zwischen den ersten beiden Szenarien auch so erwartet wurden, war das dritte einfach nur schlecht.
Nun, wie ich bereits sagte, verwendete ich den APD; dadurch kann man u.a. auch sehen, welche Funktionen und Methoden wie oft aufgerufen und – vor allem – wie viel Zeit beansprucht haben. Und siehe da, das problem lag gar nicht am XSLTProcessor, sondern an den DOMDocument::createElement() und DOMDocument::appendChild() Methoden, die nämlich zusammen bereits 50% ausmachten – neben den anderen DOMDocument-Methoden und PHP-Funktionen des Scripts.
Also was tun? Da es derzeit scheinbar keine Möglichkeit gibt, mit einem OOP-Ansatz ein XML-Dokument zu erstellen, ergriff ich eine andere Alternative, die wesentlich einfacher und effizienter ist. Man erstellt einfach Strings mit den XML-Tags, lädt diesen String anschließend als DOMDocument-Objekt durch den Processor.. und siehe da..
Total Elapsed Time = 1.19 Total System Time = 0.12 Total User Time = 0.41
Anmerkung: Die Zeiten sind kleiner, weil ein Randomize fehlt; ich Depp hab das wohl verschlampt. Die Zeiten sind natürlich (geringfügig) größer als die von “Nur-PHP”. Das korrekte Ergebnis liefere ich nach.
Und? Was sagt uns das?
XSL als Template-System ist eine Alternative. Das Processing selber ist auf keinen Fall langsamer als ein entsprechendes Smarty-Pendant. Man kann natürlich mit einem Accelerator die PHP-Files beschleunigen – gleichzeitig bestehen bei XSL-Processing die Möglichkeiten, einzelne Teilbäume aka Bereiche zu cachen. Und es sei nicht zu vergessen: Wenn irgendwann alle Browser XSL können, kann man das Transformieren auf den Client schieben.. und das ist auf jeden Fall am schnellsten!
Gleichzeitig muss man natürlich auch abwiegen, wie viel die einzelnen Möglichkeiten “können”.
XSL greift mittels XPath auf die XML-Daten zu, d.h. alles basiert auf der Graphentheorie und mit der dazugehörigen Funktionssemantik (Eltern, Kinder, Anzahl Kinder, letztes Kind, usw..). Durch zahlreiche Eigenschaften und entsprechende Funktionen besteht ein durchaus umfangreicher Funktionsschatz. Zusätzlich lassen sich, sofern man Serverside Processing verwendet, die PHP-Funktionen in das XSL einbinden.
Eins ist sicher: Mittels XSL hat man folgende, fast unschlagbaren Argumente:
- mindestens wohlgeformten XHTML-Code, sofern man im Template einmal validen XHTML-Code hat, ist es immer valid
- wirkliche Trennung von Daten (XML), Layout (XSL) und Design (CSS)
- theoretische Transformierung auf dem Client
Im Vergleich: Smarty funktioniert erstens nur auf dem Server und ist des Weiteren ein Interpreter des Smarty-Templates, welches mit dem PHP-Interpreter aufgerufen wird.. kurz gesagt: Eigentlich sinnlos.
#1 by inbreed on 17. Juni 2006 - 12:49
Zitieren
“wirkliche Trennung von Daten (XML), Layout (XSL) und Design (CSS)”
XSL ist kein Layout! XHTML ist das Layout und Ergebnis der Transformation (XSL!)
#2 by knalli on 17. Juni 2006 - 13:05
Zitieren
Ja Meister, meine ich doch.. ich habs nur falsch geschrieben *ausred*
#3 by Andre on 25. Juni 2006 - 18:18
Zitieren
Ich mag Smarty und benutze es auch in meinem Framework als Standard-Template-Engine. Und, wenn man es so betrachtet, ist es wirklich sinnlos, aber Smarty hat einige Vorteile gegenueber XSL:
1.) Leichte Erweiterbarkeit.
2.) Folgend aus dieser leichten Erweiterbarkeit eine verbesserte Trennung von Praesentation und Applikation.
3.) Ist vllt. nur Uebungssache, aber ich bin Smarty um Laengen schneller als mit XSL.
4.) Post-/Preprocessing
5.) Cache (oder kann man mit XSL auch gewisse Teile cachen?)
Wenn jeder Browser das interpretieren wuerde, waere XSL sicherlich die bessere Loesung, aber da dies noch nicht der Fall ist, bleibe ich erstmal bei Smarty.
gez. Andre
#4 by knalli on 25. Juni 2006 - 20:07
Zitieren
Ich wüsste nicht, wieso nicht.
Man muss natürlich ein “intelligentes” System aufbauen, aber man könnte Teilbereiche cachen.. dies würden aber dann nicht über XSL selber, sondern über einen höherstehenden Prozess ablaufen.
Also, zB: gesamte Seite fertig rendern, und nur die Loginbox dann einladen..