Performance TagLibs

Im Entwickler-Forum können Implementierungsdetails sowie Alternativen der Umsetzung diskutiert werden. // Here, developers can discuss implementation details of features of their projects.
Antworten
jGeee
Beiträge: 17
Registriert: 06.05.2009, 10:25:31

Performance TagLibs

Beitrag von jGeee » 17.06.2009, 17:31:51

Hallo Christian,

da bin ich mal wieder =)

Da ich mich irgendwie nicht komplett mit den TagLibs anfreunden möchte ( Performance mäßig ), hatte ich folgende kurze Überlegung um das Problem zu umgehen.

Der Template-Bauer kann weiterhin die TagLibs benutzen, jedoch wird das Template über das Backend hinzugefügt ( später ). Dann werden alle HTML TagLibs durch arrays ersetzt und das "fertige" Template wird neu gespeichert und anstatt des anderen benutzt (vom Controller). Ein Template sähe dann z.B. wie folgt aus:

Code: Alles auswählen

<?php 

$TPLItem[0] = array('taglib' => 'controller', 'namespace' => 'sites::admin', 'file' => 'start', 'class' => 'sStart');
$TPLItem[1] = 'irgendein HTML Code';
$TPLItem[2] = array('taglib' => 'html_taglib_placeholder', 'name' => 'Backend.Name');

$TPLItemToParse = array(0, 2);

?>
Ich denke aufgrund deiner Architektur in dem APF sollte es leicht einbindbar sein oder?! Hier ein kleines Beispiel-Snippet, wie es aussehen "könnte" ( ungetestet etc )

Code: Alles auswählen

      // Prüfen ob bereits eine geparste Datei vorhanden ist
      if(file_exists($FileName.$this->TemplateParsedExt) && is_file($FileName.$this->TemplateParsedExt)) 
      {
      	include($FileName.$this->TemplateParsedExt);
      	
      	if(isset($TPLItemToParse) && is_array($TPLItemToParse))
      	{
      		$countTPLItemToParse = count($TPLItemToParse);
      		
      		// TPL Elemente parsen
	      	for($i=0;$i<$countTPLItemToParse;$i++)
	      	{
	      		if(array_key_exists($TPLItemToParse[$i], $TPLItem) && is_array($TPLItem[$TPLItemToParse[$i]]))
	      		{
	      			// TagLibName setzen
	      			$TagLibName = $TPLItem[$TPLItemToParse[$i]]['taglib'];
	      			
	      			// TagLibName aus $TPL array entfernen, alle anderen werte sind parameter der Taglib
		      		unset($TPLItem[$TPLItemToParse[$i]]['taglib']); 		
						
		      		// TagLib ausführen
		      		$TPLItem[$TPLItemToParse[$i]] = $this->callTaglib($TagLibName, $TPLItem[$TPLItemToParse[$i]]);
	      		}
	      	}
      	}
      	
      	// Template wieder zusammen setzen
      	if(is_array($TPLItem))
      	{
      		$TPLItem = implode("", $TPLItem);
    
	      	if(is_string($TPLItem))
	      	{
	      		$this->__Body = $TPLItem;
	      	}
      	}
      }

Die Methode callTaglib(); habe ich nicht erstellt, weil ich nicht genau weiß wie ich das anstellen soll. Kann man die TagLibs in dem Document-Objekt nicht irgendwie einbinden?! Bräuchte vielleicht nen kleinen Denkanstoss, da ich nciht genau weiss wie das APF genau aufgebaut ist..

Würde mich über eine Antwort und Kritik deinerseits freuen :o)


Gruß und Danke, Josh

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Performance TagLibs

Beitrag von dr.e. » 17.06.2009, 20:59:41

Hallo Josh,
Da ich mich irgendwie nicht komplett mit den TagLibs anfreunden möchte ( Performance mäßig )
Dabei würde mich interessieren: warum? Die Implementierung der TagLibs ist meinen Tests nach (siehe http://adventure-php-framework.org/Seite/103-Yii-vs-APF) sehr effizient und schlägt das z.B. bei CakePHP eingesetzte Templating um Längen. Die Flexibilität bleibt dabei trotzdem erhalten, da eine TagLib durch eine PHP-Klasse repräsentiert wird, was hinterher Bytecode ist. Zudem habe ich den Gültigkeitsbereich von "bekannten" TagLibs auf Document gesetzt, sprich eine Custom-TagLib ist nur innerhalb eines sehr limitierten Umfelds bekannt, was den Parse-Vorgang linear schmal hält.

Hast du mal ein Beispiel für den Einsatz von langsamen TagLibs?
Ich denke aufgrund deiner Architektur in dem APF sollte es leicht einbindbar sein oder?!
An sich definiert das APF exakt eine Schnittstelle, mit der GUI-Elemente erweitert werden können: die Page-Controller-Implementierung. Hier hat der Entwickler die Möglichkeit, eigene TagLibs zu schreiben oder pro DOM-Baum-Element einen Document-Controller zu definieren. Für beide Bereiche wird vom Page-Controller ein "Container" zur Verfügung gestellt, der diese Elemente mit den Informationen der umliegenden GUI-Objekte versorgt (Sprache, Context, Attribute, Referenz auf das aktuelle Dokument bei Document-Controllern bzw. eine Referenz auf das Vater-Objekt bei einer TagLib).

Wenn du nun eine eigene Template-Funktion einbinden möchtest, kannst du das mit beiden Mitteln tun. Wichtig ist dabei nur, dass du dir die Flexibilität nicht nimmst, die das APF bietet. Dies ist, dass aus einem Satz an Templates ein kompletter, generischer DOM-Baum erzeugt wird, der je nach Anwendung beliebig komplex/tief strukturiert sein kann. Wenn ich in einem Knoten X ein Modul Y einhängen möchte bedeutet das einfach nur einen weiteren DOM-Knoten zu erzeugen und der Baum wird dynamisch vom Page-Controller erweitert.
Der Template-Bauer kann weiterhin die TagLibs benutzen, jedoch wird das Template über das Backend hinzugefügt ( später ).
Nur damit ich dich richtig verstehe: dir geht es darum, dass in einem "Backend" definiert werden kann, welche Templates für das Rendering von bestimmten Objekten oder Funktionen verwendet werden können? Z.B. über eine GUI, die ihre Informationen in einer Datenbank speichert?
Dann werden alle HTML TagLibs durch arrays ersetzt und das "fertige" Template wird neu gespeichert und anstatt des anderen benutzt (vom Controller). Ein Template sähe dann z.B. wie folgt aus:
An sich werden die TagLibs eines Dokuments bereits in einem Array gespeichert - als Kind-Knoten ($this->__Children). Wenn du dir mal die Methode extractTagLibTags() in der Klasse Document anschaust, wirst du ein ähnliches Muster erkennen. Unter http://adventure-php-framework.org/Seit ... ufdiagramm findest du eine Beschreibung, welche Methoden wann auf eine TagLib-Klasse aufgerufen werden. Dort gibt es Parser-Methoden, die den Tag zur Parse-Zeit initialisieren und Erzeuger-Methoden (transform()), die den transformierten Inhalt des aktuellen Knotens rendern.
Die Methode callTaglib(); habe ich nicht erstellt, weil ich nicht genau weiß wie ich das anstellen soll. Kann man die TagLibs in dem Document-Objekt nicht irgendwie einbinden?! Bräuchte vielleicht nen kleinen Denkanstoss, da ich nciht genau weiss wie das APF genau aufgebaut ist.
Dabei ist die Frage, was $TPLItemToParse genau beinhaltet und was du durch das include() bezwecken möchtest. Sofern dein callTaglib() APF-TagLibs parsen soll, ist der Code für die rekursive Bearbeitung wie folgt:

Code: Alles auswählen

function callTaglib($tagLibName,$currentItem){

   $tagLibInstance = new $tagLibName();
   ...
   $tagLibInstance->onParseTime();
   $tagLibInstance->onAfterAppend();
   return $tagLibName->transform();

}
Da ich noch nicht genau verstanden habe, was $currentItem tun soll, habe ich der Methode mal drei Punkte spendiert. :)

Noch ein Hinweis: sofern du versuchen möchtest im dynamischen Quelltext (der z.B. in einer Datenbank steht) befindlichen Redakteurs-Tags mit dieser Methode auszuführen, geht das auch einfacher. Du musst nur in der Methode onParseTime() den Inhalt aus der Datenbank laden und danach die Methode extractTagLibTags() ausführen. Dies veranlasst den Page-Controller die darin befindlichen Tags zu analysieren und als Kinder einzuhängen. In der transform()-Methode kannst du dann dafür sorgen, dass deine dynamischen Tags ausgeführt und der gewünschte Inhalt erzeugt wird.

Ich hoffe, ich konnte dir ein wenig weiter helfen.

Viele Grüße,
Christian
Viele Grüße,
Christian

jGeee
Beiträge: 17
Registriert: 06.05.2009, 10:25:31

Re: Performance TagLibs

Beitrag von jGeee » 18.06.2009, 09:05:17

Hallo Christian,

ersteinmal danke für deine Antwort, werde sie jetzt stückweise beantworten:
Dabei würde mich interessieren: warum?
Ich bin im moment bei einem größeren Projekt. Das CMS soll viele Seiten aufeinmal verwalten, welche erst einmal auch alle auf dem selben Server laufen werden und ich daher ziehmlich viel auf Perfomance achten muss. HTML zu parsen dauert viel länger, als ein Array ausseinander zunehmen. Denn diese Taglibs kann man ja auch als Array darstellen. ( Sie werden ja so oder so geparst und dann als Array erstellt, jedoch möchte ich den Parser-Schritt nicht bei jedem Request ausführen ).
Hast du mal ein Beispiel für den Einsatz von langsamen TagLibs?
Gerade im moment nicht, nein, aber es werden ziehmlich viele Templates vorhanden sein, da Community-, Business- und/oder Privatseiten darauf laufen werden, wie gesagt, soviele auf einem Server bis Performance-Probleme auftauchen.
Nur damit ich dich richtig verstehe: dir geht es darum, dass in einem "Backend" definiert werden kann, welche Templates für das Rendering von bestimmten Objekten oder Funktionen verwendet werden können? Z.B. über eine GUI, die ihre Informationen in einer Datenbank speichert?
Sogesehen schon, der Template-Bauer soll die Seite ohne jegliche Hilfe eines Programmierers erstellen können. Er kann eigene Templates definieren und gibt auch jegliche Angaben zum layout ( z.b. html, css ). Außerdem kann er dann Standartmodule für die einzelnen Webseiten laden und diese in bestimmten Templates aufrufen. Das Template wird dann einmal gespeichert (unverändert, damit der Templater es nochmals verändern kann) und einmal wird das Template geparst und als Array gespeichert ( siehe Snippet #1 ).

$TPLItemToParse speichert hierbei nur alle zu parsenden Taglibs, d.h. dass ich genau weiss, welcher Array-Index ein Taglib darstellt und auch ausgeführt werden soll. So umgehe ich halt alle String-Funktionen, welche viel Performance in der Menge brauchen.. ( wie strpos, substr, substr_count, usw )

Include() wird hierbei benutzt, anstatt deiner file_get_contents() Funktion, denn wie oben beschrieben, speicher ich das Template seperat als .php Datei ab, damit ich wie gerade gesagt nichtsoviele Stringfunktionen habe, sondern nur das Array (Snippet #1 aka Template nur als Array) ausseinander nehmen muss (Snippet #2) und nicht das Template parse..

Wegen der callTaglib Methode die du erstellt hast: Im Document-Objekt (__extractTagLibTags()) übergibst du der TagLib aber noch einige andere Attribute z.B.

Code: Alles auswählen

  // Attribute einhängen
               $Object->setAttributes($Attributes['attributes']);


               // ObjectID setzen
               $Object->set('ObjectID',$ObjectID);


               // Token-String im Content durch <$ObjectID /> ersetzen
               $Content = substr_replace($Content,'<'.$ObjectID.' />',$TagStartPos,$TagStringLength);


               // Vater bekannt machen
               $Object->setByReference('ParentObject',$this);


               // Content einbinden
               $Object->set('Content',$Attributes['content']);
Ich hoffe ich konnte dir genauer beschreiben, was ich vorhabe *g*

Danke schonmal,

Viele Grüße
Josh


edit: wozu eigtl. $Object->setByReference('ParentObject',$this); und
$Object->set('Content',$Attributes['content']); ?


PS: Habe ich das richtig verstanden, das Objekt $Page stellt eine komplette Seite mit all Ihren Templates (Document-Objekten) dar? D.h. dass für jedes Template eine Instanz der Klasse Document vorhanden ist? Und umso tiefer mann das Document schachtelt, wird immer ein Document-Objekt erstellt?!

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Performance TagLibs

Beitrag von dr.e. » 18.06.2009, 12:24:49

Hallo Josh,
Ich bin im moment bei einem größeren Projekt. Das CMS soll viele Seiten aufeinmal verwalten, welche erst einmal auch alle auf dem selben Server laufen werden und ich daher ziehmlich viel auf Perfomance achten muss. HTML zu parsen dauert viel länger, als ein Array ausseinander zunehmen. Denn diese Taglibs kann man ja auch als Array darstellen. ( Sie werden ja so oder so geparst und dann als Array erstellt, jedoch möchte ich den Parser-Schritt nicht bei jedem Request ausführen ).
OK. Ein anderer Ansatz ist hier jedoch das Thema Caching von statischen Inhalten. Du könntest im CMS ein lazy caching vorsehen, das immer dann erneuert wird, wenn der Redakteur etwas ändert. Unter http://adventure-php-framework.org/Seit ... -ein-HOWTO habe ich in einem Artikel beschrieben, wie so ein Mechanismus mit dem APF aufgesetzt werden kann. Wenn du dann noch Memcached als Backend nutzt, solltest du definitiv keine Performance-Probleme bekommen. Meiner Erfahrung nach sollte man bei Performance-kritischen Anwendungen zuerst auf eine schnelle Basis setzen (das APF kann das leisten) und dann versuchen sukzessive Caching einzuführen. Das kann über view-based caching oder einfach über Content-Caching passieren, in dem der komplette Part, den der Redakteur pflegt, nur einmal geparst und anschließend aus dem Cache gezogen wird.
Gerade im moment nicht, nein, aber es werden ziehmlich viele Templates vorhanden sein, da Community-, Business- und/oder Privatseiten darauf laufen werden, wie gesagt, soviele auf einem Server bis Performance-Probleme auftauchen.
Zum Thema Performance-Optimierung kann ich gerne unterstützen, ich habe u.A. in den letzten 4 Jahren an diesem Thema im Bereich PHP-High-Performance-Infrastrukturen gearbeitet.

Zum Templating:
Ich muss nochmal zum Verständnis rezitieren: der Templatebauer (=administrativer "Redakteur") hat die Möglichkeit Templates für die Ausgabe zu definieren. In einzelne Seiten kann er fertige Module (Kommentar, Bewertung, ...) einklinken. Diese Templates werden dann in PHP-Code übersetzt und in einer PHP-Datei abgelegt (dynamisch). Das Parsen des Inhalts einer seite erfolgt dann über das Iterieren der Tags der Seite.

Was mir noch nicht ganz klar ist: wie kommen die redaktionellen Inhalten dann in die Seite? Sprich wenn ich nun vor dem CMS-Backend sitze und möchte einen neuen Navigationsknoten mit einem neuen Inhalt zum Thema XYZ anlegen. Wie würde an dieser Stelle der programmatische Ablauf sein? Ich frag bewusst "blöd" nach, denn ich denke, dass man an dieser Stelle vielleicht das Konzept optimieren könnte. Wenn du interessiert bist, kann ich dir auch ein Beispiel geben, wie das Parsing von Benutzer-Tags angegangen werden kann. Etwas in der Art habe ich für private Projekte schon umgesetzt.
Wegen der callTaglib Methode die du erstellt hast: Im Document-Objekt (__extractTagLibTags()) übergibst du der TagLib aber noch einige andere Attribute z.B.
Richtig, mein Code war natürlich nur ein Demonstrations-Beispiel. In Wirklickeit stellt die __extractTagLibTags() einen echten dependency injection container dar, der dem neuen DOM-Knoten alle für diesen relevante Informationen mitgibt. Das sind:
  • Attribute der Tag-Definition (<my:tag name="foo" .../>).
  • Inhalt der Tag-Definition (<my:tag ...>... my content ...</my:tag>).
  • Context des aktuellen Knotens (-> Wegen Konfiguration).
  • Sprache des aktuellen Knotens (-> Wegen Konfiguration).
  • Referenz auf das Vater-Objekt (-> Für die Möglichkeit des Traversieren über den Baum).
Der neu erstellte Tag wird dabei in die Liste der Kinder des aktuellen Knotens ($this->__Children) eingehängt. Als Key dient eine UUID (ObjectID, die zur Laufzeit generiert wird).
edit: wozu eigtl. $Object->setByReference('ParentObject',$this); und
$Object->set('Content',$Attributes['content']); ?
Die erste Code-Zeile macht das Vater-Objekt bekannt, die zweite injeziert den Inhalt der Tag-Definition in den Tag, dass der Tag selbst die Möglichkeit hat, diesen weiter zu verarbeiten.
PS: Habe ich das richtig verstanden, das Objekt $Page stellt eine komplette Seite mit all Ihren Templates (Document-Objekten) dar? D.h. dass für jedes Template eine Instanz der Klasse Document vorhanden ist? Und umso tiefer mann das Document schachtelt, wird immer ein Document-Objekt erstellt?!
Genau das. Der Page-Controller erstellt dazu eine Page-Instanz mit einem initialen Document und nutzt dann die Informationen des initialen Templates um den DOM-Baum aufzubauen. Wenn du die mal http://adventure-php-framework.org/Seit ... rue#bottom ansiehst oder den Benchmarker lokal einbindest, kannst du die Baum-Struktur an Hand der Einrückung erkennen. Bis
(document) *::transform()
befindet sich der Page-Controller in der Analyse-Phase (Aufbau des APF-DOM-Baums), danach wird die Transformation des Baumes durchgeführt.

Viele Grüße,
Christian
Viele Grüße,
Christian

jGeee
Beiträge: 17
Registriert: 06.05.2009, 10:25:31

Re: Performance TagLibs

Beitrag von jGeee » 18.06.2009, 16:07:32

Hallöle,

mal wieder ein dickes Danke für die Antwort ;-)
OK. Ein anderer Ansatz ist hier jedoch das Thema Caching von statischen Inhalten. Du könntest im CMS ein lazy caching vorsehen, das immer dann erneuert wird, wenn der Redakteur etwas ändert. Unter http://adventure-php-framework.org/Seit ... -ein-HOWTO habe ich in einem Artikel beschrieben, wie so ein Mechanismus mit dem APF aufgesetzt werden kann. Wenn du dann noch Memcached als Backend nutzt, solltest du definitiv keine Performance-Probleme bekommen. Meiner Erfahrung nach sollte man bei Performance-kritischen Anwendungen zuerst auf eine schnelle Basis setzen (das APF kann das leisten) und dann versuchen sukzessive Caching einzuführen. Das kann über view-based caching oder einfach über Content-Caching passieren, in dem der komplette Part, den der Redakteur pflegt, nur einmal geparst und anschließend aus dem Cache gezogen wird.
Caching kommt natürlich auch noch ins Spiel, richtig. Wobei ich gerade nicht genau weiß, ob es dann Sinn macht die Templates in PHP zu "konvertieren". Da ich mich bisher kaum mit Caching beschäftigt habe, kenn ich die meissten Unterschiede nicht.
Was Memcaching ist, weiß ich, jedoch weiss ich nicht ob das in diesem Projekt sinnvoll ist. (Außer vllt. bei Videos?!, Der Arbeitsspeicher kann ja auch schnell zu voll werden?)
Das View-Based-Caching habe ich mir angesehen, dass werde ich aufjedenfall so umsetzen! Danke :)

Ich muss nochmal zum Verständnis rezitieren: der Templatebauer (=administrativer "Redakteur") hat die Möglichkeit Templates für die Ausgabe zu definieren. In einzelne Seiten kann er fertige Module (Kommentar, Bewertung, ...) einklinken. Diese Templates werden dann in PHP-Code übersetzt und in einer PHP-Datei abgelegt (dynamisch). Das Parsen des Inhalts einer seite erfolgt dann über das Iterieren der Tags der Seite.
Das ist so nicht ganz richtig, ich unterscheide nochmals zwischen "Administrativer Redakteur" und "Template-Bauer".
Template-Bauer: Er erstellt die komplette Seite ( HTML, Taglibs etc )
Redakteur: Ist derjenige, der überhaupt keine Ahnung hat, und lediglich die Inhalte ( z.B. den Newstitel und den Newstext ) einpflegt. Der Redakteur sieht nichts von den Templates im Backend.
Was mir noch nicht ganz klar ist: wie kommen die redaktionellen Inhalten dann in die Seite?
Der Redakteur hat nachdem die Webseite vom Template-Bauer gefertigt ist, ein Backend um die Inhalte der Module zu füllen. (Denke das der Rest klar ist, nachdem ich dir sagte das ich zwischen Template-Bauer und Redakteur unterscheide) :)
Die erste Code-Zeile macht das Vater-Objekt bekannt, die zweite injeziert den Inhalt der Tag-Definition in den Tag, dass der Tag selbst die Möglichkeit hat, diesen weiter zu verarbeiten.
Mh, ich komm irgendwie mit dem Attribut ParenObject nicht klar. Warum als Referenz setzen? ( Ebenfalls bei den Actions im coreObject..) Kannst du mir dazu vielleicht etwas mehr erzählen? :-)


EDIT: Achja, als Referenz, weil in PHP4 ein Objekt, wenn es als Parameter übergeben wird, nicht als Referenz gesetzt wird?! Naja zum glück ist das nun endlich wie in JAVA :o)
Genau das. Der Page-Controller erstellt dazu eine Page-Instanz mit einem initialen Document und nutzt dann die Informationen des initialen Templates um den DOM-Baum aufzubauen.
D.h. es gibt überhaupt keine "Seite" in der Hinsicht, sondern es wird direkt alles in den Templates und über die verfügbaren Taglibs gesteuert? Also muss ich mir das sovorstellen, dass alles Rekursiv durch das Initiale Template abgearbeitet wird?!


Großes Danke und viele Grüße
Josh

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Performance TagLibs

Beitrag von dr.e. » 18.06.2009, 23:15:48

Hallo Josh,
Das ist so nicht ganz richtig, ich unterscheide nochmals zwischen "Administrativer Redakteur" und "Template-Bauer".
Template-Bauer: Er erstellt die komplette Seite ( HTML, Taglibs etc )
Redakteur: Ist derjenige, der überhaupt keine Ahnung hat, und lediglich die Inhalte ( z.B. den Newstitel und den Newstext ) einpflegt. Der Redakteur sieht nichts von den Templates im Backend.
OK, habe ich nun verstanden, wir konzentrieren uns also auf den Template-Bauer. :)
Mh, ich komm irgendwie mit dem Attribut ParenObject nicht klar. Warum als Referenz setzen? ( Ebenfalls bei den Actions im coreObject..) Kannst du mir dazu vielleicht etwas mehr erzählen? :-)
Um einen Baum aufzubauen benötigst du immer eine Art verkettete Liste. In diesem Fall erfolgt die Verkettung durch eine Referenz auf das Vater-Objekt. Weiterhin muss natürlich ein Knoten des Baumes seine Kinder kennen um überhaupt die Möglichkeit zu bieten einen Baum zu erstellen. Letzteres würde an sich reichen, jedoch ist es an verschiedenen Stellen notwendig, dass ein Kind seinen Vater kennt und nicht nur umgekehrt. Bestes Beispiel: Formular-Tags. Hier muss ein Feld (Kind-Objekt) dem Formular (Vater-Objekt) mitteilen können, dass es selbst valide/nicht valide ist, damit bei der Verwendung des Formulars von AUssen (z.B. in einem Document-Controller) dieses seinen Status auch kennt. Um die genannte Funktionalität bereit zu stellen, wird deshalb bei der Erzeugung eines Knotens immer eine Referenz auf das aktuelle Objekt (Vater) injiziert. Referenz deshalb, weil ein Knoten ein-eindeutig ist.

Der Baum besteht also immer aus einer Struktur von Knoten, die selbst ihre Kinder komponieren (=beinhalten) und ihren Vater kennen (Referenz).
EDIT: Achja, als Referenz, weil in PHP4 ein Objekt, wenn es als Parameter übergeben wird, nicht als Referenz gesetzt wird?! Naja zum glück ist das nun endlich wie in JAVA :o)
Die Methode ist namentlich mehr als Gedankenstütze gedacht, da PHP4 Referenzen nur dann ausprägt, wenn der Referenz-Operator "&" gesetzt ist. In PHP5 könnte man auch einfach die set()-Methode aus coreObject nutzen, denn dort wird vorrangig per Referenz übergeben. Schaden tut das aber auch in PHP5 nichts. :)

Apropos JAVA: hier ist zwar zunächst (fast) alles eine Referenz auf den Heap-SPace, dafür gibt es aber beim Vergleich zweier Objekte einige nette Fallstricke. ;-)
D.h. es gibt überhaupt keine "Seite" in der Hinsicht, sondern es wird direkt alles in den Templates und über die verfügbaren Taglibs gesteuert? Also muss ich mir das sovorstellen, dass alles Rekursiv durch das Initiale Template abgearbeitet wird?!
Exakt so. Was deine eigentliche "Webseite" letztlich an Inhalten besitzt ist abhängig davon, was du in die Templates schreibst. Durch die implizite MVC-Struktur (jeder Knoten des Baumes ist eigentlich eine Zelle einer H(irarchischen)-MVC-Struktur) kannst du beliebig auslagern und einbinden, so dass du eine möglichst hohe Wiederverwendung der Komponenten erreichst. So kannst du z.B. mit einem <core:importdesign /> einen neuen DOM-Knoten mit dem gewählten Template erzeugen oder mit dem <core:appendnode /> Template-Fragmente in den aktuellen Knoten einbinden. Über letzteren Tag kannst du z.B. in einem Template ein Formular definieren (z.B. für Login) und in n Templates wiederverwenden.
Genauso kannst du über den importdesign-Tag Teile der Webseite in eigene Templates auslagern (Header, Footer, Content, Menü, ...) und anschließend in einem Haupt-Template zusammenfügen. Unter http://adventure-php-framework.org/Seit ... el-der-GUI habe ich dazu mal ein Beispiel aufgemalt, das die Struktur ein wenig verdeutlicht.
Caching kommt natürlich auch noch ins Spiel, richtig. Wobei ich gerade nicht genau weiß, ob es dann Sinn macht die Templates in PHP zu "konvertieren". Da ich mich bisher kaum mit Caching beschäftigt habe, kenn ich die meissten Unterschiede nicht.
Grundsätzlich hast du sicher in den Templates Platzhalter, die der Redakteur für die Ausgabe bestimmter dynamischer Inhalte setzen kann. Um diese nicht jedes mal interpretieren zu müssen (=HTML-Code generieren) kannst du beim ersten Aufruf die Interpretation vornehmen und das Ergebnis speichern. Beim nächsten Request kannst du dann das fertige Generat nutzen um einen Teil der Webseite (z.B. Content-Bereich) auszuliefern. An sich ein ähnliches / erweitertes Konzept zum view based caching. Wenn du möchtest, stelle ich dir mal ein Beispiel zur Verfügung.
Was Memcaching ist, weiß ich, jedoch weiss ich nicht ob das in diesem Projekt sinnvoll ist. (Außer vllt. bei Videos?!, Der Arbeitsspeicher kann ja auch schnell zu voll werden?)
Um gute Performance garantieren zu können, sollten HTML-Seiten üblicherweise nicht größer als 20kB (reiner Quelltext!) sein. Nehmen wir an, du hast etwa 100 Content-Seiten, so würden sich im Speicher 2MB befinden, was einen Server nicht ansatzweise stören sollte. Sollte das direkte Caching von HTML ein Problem sein, kannst du ja immer noch Objekt-Strukturen cachen, sprich einen Menü-Baum, eine Footer-Navigation, aktuell anzuzeigende Bilder in einer Banner-Rotation, ...
Es gibt viele Arten der Optimierung und ich bin grundsätzlich ein Freund davon, die Applikation zunächst zu implementieren und dann eine Optimierung vorzunehmen. Dann ist es oft viel einfacher zu sehen, wo welche Methode nützlich ist. Zudem hilft dir während der Entwicklung ja immer wieder der Benchmarker um zu sehen, wo wieviel Zeit verbraucht wird. Diesen solltest du daher an den zentralen Stellen immer mal einbinden um gute Aussagen über die Grund-Performance treffen zu können. Verwendest du die Standard-APF-Mechanismen zum Aufbau einer Seite werden für dich bereits die wichtigsten Punkte (Parsing, Transformation) gemessen.

Viele Grüße,
Christian
Viele Grüße,
Christian

jGeee
Beiträge: 17
Registriert: 06.05.2009, 10:25:31

Re: Performance TagLibs

Beitrag von jGeee » 19.06.2009, 00:58:16

Nabend Christian,

hab mich leider ein wenig Verspätet :)

Vielen Dank für die Beschreibung. Jetzt wird mir einiges klarer :o).
Grundsätzlich hast du sicher in den Templates Platzhalter, die der Redakteur für die Ausgabe bestimmter dynamischer Inhalte setzen kann. Um diese nicht jedes mal interpretieren zu müssen (=HTML-Code generieren) kannst du beim ersten Aufruf die Interpretation vornehmen und das Ergebnis speichern. Beim nächsten Request kannst du dann das fertige Generat nutzen um einen Teil der Webseite (z.B. Content-Bereich) auszuliefern. An sich ein ähnliches / erweitertes Konzept zum view based caching. Wenn du möchtest, stelle ich dir mal ein Beispiel zur Verfügung.
Richtig, genau so :). Ja ein Beispiel wie man es mit dem APF umsetzt, wäre sehr lieb, oder ist es das view-based-caching? ( http://adventure-php-framework.org/Seit ... -ein-HOWTO ) *g*


Ich melde mich bestimmt bald nochmal :P

Danke für dein Bemühen,

Josh

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Performance TagLibs

Beitrag von dr.e. » 19.06.2009, 07:52:40

Hallo Josh,

kein Problem, ich stelle dir bis Samstag ein bischen Code und Text zusammen, dann kannst du ungefähr sehen, wie eine Implementierung mit dem APF aussehen kann.

Bis dahin kannst du ja schon mal beginnen, ohne Caching das Grundgerüst der Seite (z.B. nach http://adventure-php-framework.org/Seit ... -erstellen) zu erstellen.
Ich melde mich bestimmt bald nochmal :P
Dafür bin ich da! :)

Viele Grüße,
Christian

EDIT: Schau dir mal viewtopic.php?f=1&t=80&p=562&hilit=cms#p562 an, den dort zur Verfügung gestellten Code und die Beschreibungen dazu könnten dir vielleicht bis dahin auch schon weiter helfen. Insbesondere könntest du dir den Ordner apps/3rdparty/cmscontentparser/ ansehen, der ist dafür verantwortlich, dass Custom-Tags geparst werden. Im Controller apps/sites/adminpanel/pres/documentcontroller/cmspanel/cmsanzeigen_v1_controller.php wird dieser dann verwendet.
Viele Grüße,
Christian

Benutzeravatar
dr.e.
Administrator
Beiträge: 4527
Registriert: 04.11.2007, 16:13:53

Re: Performance TagLibs

Beitrag von dr.e. » 20.06.2009, 18:04:27

Hallo Josh,

wie besprochen habe ich unter Dynamische Ausgabe von Datenbank-Inhalten einen neuen FAQ-Eintrag erstellt, der erläutert, wie die Implementierung eines dynamischen Platzhalter-Parsers mit Hilfe eines APF-Document-Controller implementiert werden kann.

Dies ist natürlich nicht die einzig mögliche Methode, man könnte auch über eine Lösung via TagLibs nachdenken. Dies würde sogar den Vorteil bieten, dass die Tags des Redakteurs "echte" APF-Tags sein können und diese nach dem Laden des Inhalts aus der Datenbank innerhalb der TagLib einfach durch den Page-Controller analysiert und als Kinder des Content-Bereichs behandelt werden.

Solltest du Fragen haben, können wir diese gerne hier diskutieren.

Viele Grüße,
Christian
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast