Performance-Optimierung für den Blog
22. Mai 2008, 179 Mal gelesen.
| ||
Vor einiger Zeit schon beschäftigte ich mich mit der Geschwindigkeit meines Blogs. Inzwischen habe ich einiges an Erfahrung dazu gewonnen, weshalb nun ein massiv aktualisierter Beitrag entstanden ist. Ausschlaggebend waren die Ladezeiten meines Blogs, die mir schon ein bisschen krass vorkamen. Als ich mal alle Plugins deaktiviert hatte, lief alles blitzeschnell. Hier ist aber gleich auf mehrere Dinge zu achten, auf die ich im Folgenden genauer eingehen werde. Wichtig ist auch eine Optimierung der Datenbank und der Bereitstellung diverser Javascript-Frameworks.
- Der Webserver:
Als großer Flaschenhals kann sich die Ausstattung des PCs, auf dem die Webseite gehostet ist, herausstellen. Um die ganzen php-Anfragen in einer vernünftigen Geschwindigkeit abarbeiten zu können, ist auf entsprechende Prozessorpower und Größe des Arbeitsspeichers zu achten. Gott sei Dank wurde mein Server inzwischen aufgebohrt, was auch einen deutlichen Performance-Schub spürbar machen lässt. Neben den Ausführungen in diesem Beitrag ist also immer auch an die Permformance des Servers zu denken. So kann es beispielsweise sehr kontraproduktiv sein, Dateien “on the fly” zippen zu lassen. Das Datenvolumen ist dadurch zwar geringer, aber möglicherweise dauert das Packen der Dateien deutlich länger als das bloße Bereitstellen der unkomprimierten Daten. Hier ist also unbedingt darauf zu achten, dass die gezippten Files auch zwischengespeichert werden, damit die Berechnung nicht bei jedem Zugriff erfolgen muss. Server-seitig gibt es natürlich eine ganze Fülle an Optimierungsmöglichkeiten wie php-Beschleuniger, etc. - php-Anfragen der Plugins:
Um die php-Anfragen generell geringer zu halten, empfiehlt es sich nicht nur, sich auf die wesentlichen Plugins und Erweiterungen festzulegen, sondern auch die inaktiven Plugins, die nicht gebraucht werden, effektiv vom Server zu fegen. Angeblich sind nämlich selbst durch nicht aktivierte Plugins Performance-Einbußen zu erwarten. Zudem gibt es immer mehrere Plugins, die praktisch das gleiche Ergebnis bringen. Wie in dem wunderbaren Beitrag auf Basic Thinking Blog zu erfahren ist, ist dabei die Anzahl an Datenbankabfragen ganz unterschiedlich. Es gibt also auch einige wirklich dumme Plugins, die es zu vermeiden gilt. Besonders langsam sind die Plugins, die auch noch auf externe Quellen zugreifen müssen, wie beispielsweise Addthis und Ähnliches. Das Plugin Debug Queries von Bueltge liefert hierzu gute Infos und zeigt beispielsweise, dass es auch bei meinem Blog gerade in diesem Bereich noch einiges zu verbessern gäbe :p - php-Anfragen des Themes:
Generell hat man sich nach anfänglichen Experimenten nach einer gewissen Zeit auf ein einzelnes Theme festgelegt, möglicherweise auch auf eine geringe Anzahl, zwischen denen der Besucher dann hin- und herschalten kann. So bietet es sich an, die Dateien der Themes zu optimieren und für den eigenen Bedarf anzupassen. Um die Anfragen im Theme möglichst gering zu halten, sollte definitiv auch insbesondere der Header und Footer-Bereich an den eigenen Blog adaptiert werden. So können sämtliche php-Einträge wie bloginfo(’name’), wp_title() oder va. sämtliche URL-Abfragen zB für Feed, Pingback, Image-Verzeichnis, etc. durch die entsprechenden Werte direkt ersetzt werden. All diese Dinge werden sich ja nicht mehr ändern und können daher hardcoded werden. - HTTP-Requests minimieren
Der große Vorteil des weiter unten nochmals beschriebenen PHP Speedy -Plugins ist die Minimierung der http-Requests, da sowohl js-Files als auch css-Dateien in je eine Datei zusammen gefasst werden. Das kann schon mal einen netten Performance-Boost bringen. Das ebenso unten detaillierter erklärte php-Script SmartOptimizer verfügt über ähnliche Features. Sein Vorgänger JSmart hatte viele Optimierungen noch nicht integriert, weshalb man unbedingt auf die neueste Version umsteigen sollte! Neben den vielen verschiedenen css- und js-Dateien durch den Einsatz mehrerer Plugins stellen auch mittels css eingebundene Bilddateien ein Problem dar. Nutzt man wie ich beispielsweise CSS, um nette Icons zu Links hinzuzufügen, erhöht sich die Zahl der http-Requests eventuell rapide. Auch Plugins und Scripts wie Lightview fordern eine größere Anzahl an css-Images an. Einen Geschwindigkeitsgewinn kann man durch das Nutzen von so genannten Sprites erzielen. Auf phpperformance.de gibt es ausführliche Informationen zum Einsatz von diesen CSS-Sprites. - Datenbank-Optimierungen:
Leider bieten viel zu wenige Plugins die Möglichkeit, beim Deaktivieren auch alle Optionen zu löschen. Manche wiederum löschen sämtliche Einträge in der Datenbank automatisch, was natürlich auch nicht sonderlich sinnvoll ist. Hier muss man also Vorsicht walten lassen und die Dokumentationen der einzelnen Erweiterungen genauer durchlesen. Der Regelfall ist aber wie erwähnt der, dass im Zuge von Plugintests ein Haufen sinnloser Einträge die Datenbank zupflastert. Bis zu einem gewissen Anteil kann man die Optionen natürlich selbst heraus löschen, allerdings empfiehlt sich hier der Gebrauch eines guten, wenn auch älteren, Plugins: Clean Options. Dieses Tool listet sämtliche nicht benötigten Optionen auf, die man nun einzeln anwählen und löschen kann. In diesem Zusammenhang möchte ich auch auf das DB-Manager-Plugin von LesterChan hinweisen, das bei keiner Wordpress-Installation fehlen darf. Hier kann man neben manuellen Backups auch automatisierte Sicherungskopien erstellen lassen und beispielsweise auch in gewissen Abständen die Datenbank optimieren. Letzteres führt die klassischen Defragmentierungen zum Verhindern des Overheads durch. - Optimieren von CSS-Dateien
Möchte man CSS-Dateien optimieren, empfiehlt es sich, die CSS-Files auf folgender Webseite durchlaufen zu lassen: CSS Formatierer und Optimierer. Dies ist die mit Abstand beste Methode, seine Stylesheets zu optimieren, da das Minifying sehr schön konfigurierbar ist. So werden beispielsweise durch “hohe Komprimierung” alle unnötige Leerzeichen entfernt, die Zeilenumbrüche bleiben jedoch noch bestehen, was leider nicht alle Minifyer beherrschen. Genial sind auch die Optionen zum Zusammenfassen von gleichen Deklarationen und Sortieren. Diese Prozedur minimiert daher nicht nur die Dateien, sondern ordnet sie auch noch recht übersichtlich. Aus diesem Grund empfehle ich die Nutzung des Formatierers auf jeden Fall zumindest für das Haupt-Stylesheet. Bei anderen css-Dateien, beispielsweise von Plugins, würde ich hingegen schlichtweg das unten beschriebene SmartOptimization oder php-Speedy die Arbeit automatisiert verrichten lassen. Das spart Zeit und Nerven und funktioniert wunderbar. - Optimieren von Javascript-Dateien:
Sehr wichtig ist auch das Packen von Javascript-Dateien - wobei hier jederzeit an den oben erwähnten Flaschenhals zu denken ist. Hier gibt es im Netz ein paar gute Quellen für verschmolzene Scriptaculous+Prototype-Skripte oder auch optimierte jquery-Files. Möchte man andere Script-Dateien mittels klassischem Web-Packer wie der von Dean Edwards optimieren, sind sie teilweise nicht mehr brauchbar. Sehr zu empfehlen ist hier das Java-Paket YuiCompressor. Nachdem das Paket am eigenen Rechner startbereit ist, kopiert man sich die zu komprimierenden Dateien ins gleiche Verzeichnis und führt folgenden Befehl aus:
-
java -jar yuicompressor.jar Eingabefile.js -o Ausgabefile.js
- Verhindern mehrmaliger und sinnloser Javascript-Anfragen:
Besonders wichtig ist es dann, im Header und Footer einer Seite durchzuchecken, ob ein Script mehrmals geladen wird, was durchaus passieren kann! Beim Wordpress Script-Loader ist beispielsweise auffallend, dass das komplette Scriptaculous-Framework geladen wird, wenn man auch beispielsweise nur den effects-Teil laden möchte. Es kann also gut sein, dass noch mehr Javascript-Files geladen werden als nötig sind, auch wenn die wp_enqueue-Funktion verwendet wurde. In solch einem Fall empfiehlt es sich, die effects.js-Datei über den scriptaculous.js?load=effects aufzurufen. Allerdings sollte man sich auf Grund der Größe des effects-Files (38KB unpacked) wieder den Griff zum kombinierten Protoculous-File überlegen. Dieses hat nur 61 KB und ist somit kleiner als die beiden einzelnen komprimierten Dateien prototype.js (46KB) und effects.js (24 KB). Außerdem hat man dadurch den weiteren Vorteil, dass es zu keinen Problemen beim Laden der Effekte kommen kann, was nämlich durch oben erwähnten load-Befehlt durchaus mal passieren kann. - Mehrfaches Nutzen eines Frameworks und Konfliktlösungen:
Optimal wäre natürlich auch eine Abstimmung der verschiedenen Skripte, die man nutzt. Einige Plugins basieren auf den gleichen Frameworks, andere wiederum eben nicht. Nutzt man beispielsweise ein Popup-Skript, das jquery verlangt und ein Tooltip-Skript, das auf Prototype basiert, sollte man sich vielleicht nach Alternativen umsuchen, um auch nur eine diesere js-Files laden zu müssen. Ist ein Plugin sauber programmiert, nutzt es den wp_enqueue-Befehl, um ein Javascriptfile zu laden. Sollte dies nicht der Fall sein, kann es eben durchaus passieren, dass eine Datei mehrmals geladen wird. Im Übrigen vertragen sich Prototype und jQuery nur bedingt. Sollten irgendwelche Fehlermeldungen kommen, dass eine Funktion nicht funktioniert, muss folgender Code - am besten im Footer deines Themes und im Admin-Footer - eingetragen werden:
-
<script type="text/javascript">jQuery.noConflict();</script>
- Cachen und Zippen der Dateien:
Hier gibt es unterschiedlichen Methoden. Sehr sauber erledigt das WP-Cache-Plugin praktisch alle nötigen Aufgaben, jedoch fehlt hier noch die Kompression, die noch einiges an Performance herauskitzeln kann. Dieses Problem wird von der Weiterentwicklung namens WP-Super Cache gelöst, allerdings hatte ich hier so meine Probleme. Mein Blog liegt in einem Unterverzeichnis und die htaccess-Befehle beinhalten automatisch diesen Unterordner, definieren ihn aber auch als Rewrite-Base. Und hier scheint sich die Katze in den Schwanz zu beißen. Entwerfe ich die Unterverzeichnis-Einträge aus den conditions und rules, dann funktioniert das Plugin. Es erstellt so aus den php-Seiten eine html-Seite und komprimiert diese auch noch. Wunderbar - jetzt müssen nur noch css und Javascript-Files komprimiert werden. Nach dem Testen verschiedenster on-the-fly Skripte blieb ich bei SmartOptimizer, weil dieses Skript von Anfang an funktionierte und seine Arbeit simpel und schnell zu erledigen scheint. Neben dem Komprimieren nutzt das Plugin den Minify-Modus und cacht die gezippten Files. Nicht unerwähnt bleiben soll die Diskussion, ob nun packed oder minified-Dateien besser sind. Fakt ist, dass das reine Minimieren der Variablen und Leerräume keine derart kleinen Dateien wie der Packer von Dean Edwards produziert. Allerdings sind die minified Dateien deutlich besser und leichter zu komprimieren, wodurch bei aktiviertem gzipping der ursprüngliche Größennachteil wieder wett gemacht wird. Ob nun die Response Time bei minified Dateien geringer als bei packed Files ist, wie Eric Martin bei seinem Vergleich von Optimierungsmethoden behauptet, sei hier mal dahin gestellt. Unabhängig davon verrichtet SmartOptimizer seine Zipping-Aufgaben hervorragend. Wer keine Möglichkeit hat, seine htaccess-Datei zu ändern oder das Ganze einfach lieber per Plugin steuern möchte, sollte auf jeden Fall das geniale PHP Speedy-Plugin testen. Ganz wichtig ist, die Script-Aufrufe im Header zu platzieren, im Footer werden sie ignoriert. Besonders massiv wirkt sich übrigens das Zippen der html-Seite selbst aus, was mit php Speedy eigentlich möglich wäre - ich würde hier dennoch auf die gzip-Funktion des WP Super Cache-Plugins zurück greifen. So kann der Code auf beinahe ein Fünftel reduziert werden. Aus den 92KB meiner Startseite wurden nach Aktivieren der zip-Funktion von WP-Super-Cache gerade mal 22KB! Die eine odere andere php-Datei wird nicht gepackt, beispielsweise Ajax-spezifische Aufrufe oder auch in php-Files verpackte Javascript-Funktionen. Möchte man auch diese wenigen Ausreißer zippen, empfiehlt sich das Gzip Output Plugin von Filosofo, das die bis WordPress 2.3 existente zip-Option im Admin-Menü wunderbar ersetzt. Die Funktion ist unter Umständen auch durch einen simplen Eintrag in der htaccess-Datei ohne Plugin-Schnickschnack möglich, was aber vom Serversetup abhängt. So oder so ist ein zusätzliches Zippen meiner Meinung nach nicht nötig, zumal die Dateien nicht gecachet werden und somit der Performancegewinn sehr gering ausfallen könnte. Die Datei “.htaccess” im Root-Ordner des Blogs hat folgendermaßen auszusehen, um sowohl SmartOptimizer als auch WP-Super-Cache korrekt anzusteuern:
-
# BEGIN WPSuperCache
-
SetEnv HTTP_IF_GZ_MATCH .html
-
SetEnvIfNoCase ^Accept-Encoding$ "(.*gzip.*)" HTTP_IF_GZ_MATCH=.html.gz
-
RewriteCond %{ENV:REDIRECT_STATUS} !=200
-
RewriteCond %{QUERY_STRING} !s
-
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.+)\ HTTP/ [NC]
-
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
-
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/%1/index%{ENV:HTTP_IF_GZ_MATCH} -f
-
RewriteRule ^(.*)$ /wp-content/cache/supercache/$1/index%{ENV:HTTP_IF_GZ_MATCH} [L,NC]
-
# END WPSuperCache
-
-
# BEGIN SmartOptimizer
-
<ifmodule mod_expires.c>
-
<filesmatch "\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt)$">
-
ExpiresActive On
-
ExpiresDefault "access plus 10 years"
-
</filesmatch>
-
</ifmodule>
-
<ifmodule mod_rewrite.c>
-
RewriteEngine On
-
-
RewriteCond %{REQUEST_FILENAME} !-f
-
RewriteCond %{REQUEST_FILENAME} !-d
-
RewriteRule ^(.*\.(js|css))$ smartoptimizer/?$1
-
-
</ifmodule><ifmodule mod_expires.c>
-
RewriteCond %{REQUEST_FILENAME} -f
-
RewriteRule ^(.*\.(js|css|html?|xml|txt))$ smartoptimizer/?$1
-
</ifmodule>
-
-
<ifmodule !mod_expires.c>
-
RewriteCond %{REQUEST_FILENAME} -f
-
RewriteRule ^(.*\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt))$ smartoptimizer/?$1
-
</ifmodule>
-
-
<filesmatch "\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt)$">
-
FileETag none
-
</filesmatch>
-
#END SmartOptimizer
- Expires-Header:
Zum Schluss hab ich noch für die gesamte Seite mittels Expires-Einstellungen in der htaccess-Datei das clientseitige Browsercaching aktiviert. Hierfür gibt es im Prinzip zwei idente Herangehensweisen, welche man wählt hängt von der Konfiguration ab. Ich würde hier aber schlichtweg den Einsatz der bereits beschriebenen Tools empfehlen: php Speedy als Plugin oder SmartOptimizer als Script via htaccess. Beide können Expires-Header problemlos setzen. Letzteres geht hier übrigens mehrere Wege und schafft es auch, ETags zu entfernen. Aus diesem Grund nutze ich den Optimizer zusätzlich zu php Speedy, wobei das Plugin sonst eh praktisch alle Aufgaben alleine bewältigt.
Als Hilfe zum Optimieren einer Webseite bieten sich ein paar Firefox-Erweiterungen an. Ich habe neben Firebug nun auch YSlow installiert. Letzteres ist glaub ich nicht ganz so bekannt und wirklich empfehlenswert. Allerdings scheinen die Anweisungen nicht immer ganz sauber sein, denn es kann durchaus sein, dass man für die eigene Seite eine schlechte F-Note erhält und durch Umstellen einer kleinen Sache plötzlich ein B. Das ist oft nicht ganz nachvollziehen. Aber einen generellen Überblick über mögliche Probleme bekommt man, den man weiters als Ansatz für weitere Optimierungen nutzen kann. Gerade der Tab “Components” gibt einen genialen Überblick über die geladenen Elemente, die Zugriffszeit und Komprimierung der einzelnen geladenen Files. Viel Spaß beim Tweaken eures eigenen Blogs. Sollte ich hier irgendwelche ungenauen und ungültigen Angaben gemacht bitte ich um entsprechenden Kommentar. Natürlich könnt ihr auch gerne auf weitere Optimierungsmöglichkeiten hinweisen.
Vor Jahr und Tag..
- Datum: 22. Mai 2008
- Kategorie: Medien/Onlinemedien
- Wortanzahl: 2101 Wörter
Hallo Andy,
ich möchte wp-supercache benutzen. (blog im unterverzeichnis). Habe leider keine Ahnung von htaccees & rewrite-rules-syntax. Was genau hast du gemacht, um wp-supercache zum laufen zu bekommen?
Gruss
Peter “un loco”
Hi Peter!
Im txt-File des Plugins müsste der Code für die htaccess-Datei gelistet sein. Ich habe jedoch auf einer anderen Seite gelesen, dass dieser Code nicht besonders effizient wäre. Ich habe daher den angeblich optimierten Code in meinen Artikel integriert. Einfach oben nachlesen!
Viel Glück,
Andy