phpbar.de logo

Mailinglisten-Archive

[php] Mein BBCode verlangsamt meine Seite erheblich

[php] Mein BBCode verlangsamt meine Seite erheblich

Yannik Hampe yannik at cipher-code.de
Son Jan 14 14:01:10 CET 2007



Matthias Schlich wrote:
> Hallo liebe PHP-Gemeinde,
Hallo Matthias,

> ich hoffe ihr könnt mir bei meinem Problem helfen.
> Ich betreibe auf meinem root-sever eine kleine Community.
> Dabei setze ich ein CMS ein (Ilch - www.ilch.de), das keinen richtigen 
> bbcode nutzt,
> daher hab ich ein "fremdes" Modul installiert, dass diese Lücke schließt.
> Nun zu meinem Problem: Wenn ich über den uns allbekannten code 
> [img]bild.jpg[/img]
> ein Bild einfügen möchte, so prüft der bbcode zuerst die pixel-größe des 
> Bildes um es
> evt zu verkleinern wenn es eine gewisse höhe und breite überschreitet.
> Diese Funktion arbeitet natürlich mit 'getimagesize' und verlangsamt 
> damit meine Seite
> ERHEBLICH wenn server-externe Bilder geladen werden. Liegen die Bilder 
> jedoch auf meinem Server, arbeitet das System in einer sehr guten 
> geschwindigkeit.
> Ich will jetzt natürlich den bbcode erhalten und meine Seite schneller 
> machen.
> Meinen Usern zu sagen sie sollen alle Bilder die sie im Forum posten auf 
> meinen Server zu laden,
> ist natürlich auch nicht wirklich eine Option.
> Dazu habe ich einmal den betreffenden Code hochgeladen unter:
> http://www.matthias-schlich.de/bbcode_img.txt
> Es handelt sich hier nur um die img-funktion. Falls gewünscht, kann ich 
> den Rest des BBCodes auch hochladen.
> Außerdem ist mir folgendes aufgefallen: Das CMS läd alles von oben nach 
> unten der Reihenfolge nach. Also wenn man im Forum einen Artikel mit 
> Bildern aufruft, läd das Script den Text nur bis zum ersten Bild aus der 
> Datenbank, dann kümmert es sich um das Bild und erst wenn das Bild 
> vollständig geladen hat, geht es mit dem Text weiter. Eine erhebliche 
> Erleichterung wäre es, wenn zu erst der gesammte Text laden würde und 
> sich das Script erst dann um das Bild kümmern könnte, so wie in jedem 
> anderen bulletinboard auch.

Es ist grundsätzlich schonmal eine schlechte Idee den BBCode JEDESMAL zu
parsen, wenn er angezeigt werden soll.
Das ist nämlich entweder viel zu langsam (regex,...) oder unsicher
(str_replace()).
Du solltest beim editieren eines Eintrags den Eintrag "vorparsen".
phpBB macht das Beispielsweise so:

Text des users:
$text ='bla [b]blubb[/b] foobar';
$randomid ='zufall'; //bei phpBB ist das ein zufälliger Hexwert.
$text
=preg_replace('/\\[b\\](.*?)\\[/b\\]/',"[b:$randomid]\\1[/b:$randomid]",$text);

In $text steht jetzt:
bla [b:zufall]blubb[/b:zufall] foobar

$text und $randomid speicherst du dann in der Datenbank.
Und beim Anzeigen musst du nurnoch:
str_replace(Array("[b:$randomid]","[/b:$randomid]"),Array('<b>','</b>'),$text);
machen.
Das ist deutlich schneller als das regex JEDES MAL beim anzeigen wieder
anzuwenden. Trotzdem kannst du aus dieser Zwischenform auch wieder den
bbcode erstellen, den der User am Anfang erstellt hat.

Was soll die $randomid??
Stell dir vor du hast
$text ='[b]';
Dann würde str_replace dir da den öffnenden Tag <b> hinschreiben, aber
der Tag würde nie wieder geschlossen werden. So kannst du dir das
aussehen der ganzen Seite kaputt machen, oder schlimmeres. Die randomid
verhindert das. Denn da diese bei jedem editieren neu generiert wird,
ist sie unbekannt für den Verfasser und der muss es erst mal schaffen
die randomid zu treffen. Dies ist keine 100%-Lösung, aber je nach länge
der $randomid eine 99,999999999999%-ige. Und der Performancegewinn ist
es wert.

Bei Bildern ist das natürlich schon etwas schwieriger, denn du musst die
Grösse deines Bildes irgendwie speichern. Das ist der Punkt, wo phpBB
aufgibt und doch wieder preg_replace nimmt. Aber unmöglich wäre es
nicht. Du kannst zum Beispiel etwas in der Form generieren:
[img:$randomid]src="source" width="breite" height="höhe"[/img:$randomid]
mit
str_replace(Array("[img:$randomid]","[/img:$randomid]"),Array('<img
','>'),$text);
Den html-Text generieren...
preg_replace("/\\[img:$randomid]src=".*?"\\[/img:$randomid\\]/",'[img]\\1[/img]');
kannst du dann wieder den bbcode generieren.
(Den Teil habe ich mir gerade so im Kopf zusammen gebastelt. Also keine
Garantie! Absolut ungetestet!).
(Oder du kannst bei dem Schutz darauf verzichten, dass der User das Bild
nach dem erstellen des Beitrags durch ein riesen Teil austauscht. Oder
einfach vorschreiben, dass das Bild auf deinem Sever liegen muss, damit
der user das Bild nicht einfach austauschen kann.)

Zu guter letzt: Wenn ich mir den qt ansehe, den du uns zur Verfügung
stellst, stelle ich fest, dass der Autor scheinbar grundsätzlich kein
Performanceprofi war... Also schreib' es besser selber neu, oder nimm
ein anderes Plugin...

Yannik

php::bar PHP Wiki   -   Listenarchive