WordPress ma opinię skryptu który obciąża serwery. Jeżeli blog ma zaledwie kilka odwiedzin dziennie to nie ma problemu. Gorzej jest gdy ilość odwiedzin jest już liczona w setkach czy tysiącach – wtedy optymalizacja WordPress’a jest już koniecznością.

Do wyboru jest kilka różnych metod – cache obiektów wbudowane w WordPress’a, pluginy cache’ujące i odpowiednie mechanizmy serwera, konfigurowane poprzez plik .htaccess.

Pierwszym mechanizmem jest cache obiektów wbudowane w WordPress’a. Służy ono  do przechowywania wyników zapytań SQL. Warto go włączyć aby odciążyć bazę danych. W tym celu należy do pliku wp-config.php dodać poniższą linijkę. Linijkę tę warto dodać gdzieś na początku tego pliku.

define('WP_CACHE', true);

Jeżeli chcesz zobaczyć statystyki wykorzystania object cache, to polecam zainstalować plugin WP Cache Inspect. Po włączeniu opcji „Data in Frontend” na stronach loga będzie wyświetlać się okienko ze statystykami. Polecam na czas testów wyłączyć też pluginy typu WP Super Cache, aby mieć pewność że zobaczysz te statystyki.

Drugą opcją są pluginy cache’ujące. Jednym z nich jest DB Cache DB Cache Reloaded. Pierwszy z nich służy do cache’owania wyników zapytań do bazy danych. Ponieważ nie wszystkie zapytania przechodzą przez wspomniany wcześniej object cache, warto go też zainstalować. Po instalacji trzeba go dodatkowo włączyć na stronie jego konfiguracji.

Drugim pluginem jest WP Super Cache. Plugin ten zapisuje wygenerowane strony na dysku. Dzięki temu przy kolejnych odwołaniach do serwera mogą one zostać użyte – serwowanie statycznych plików jest o wiele mniej kosztowne niż ich ponowne generowanie.

Po instalacji tego pluginu trzeba go włączyć na stronie jego konfiguracji, podobnie jak DB Cache. Aby w pełni wykorzystać jego możliwości, musisz jeszcze dodać odpowiednie wpisy do dwóch plików .htaccess: do tego umieszczonego w katalogu głównym (wpisy muszą być dodane powyżej tych dodanych przez WordPress’a), oraz do pliku /wp-content/cache/.htaccess. Reguły te znajdziesz na stronie konfiguracji pluginu WP Super Cache (aby je zobaczyć, musisz najpierw włączyć plugin).

Ostatnią metodą optymalizacji jest wykorzystanie możliwości jakie daje cache przeglądarek (trzeba wysłać odpowiednie nagłówki do przeglądarki), oraz użycie kompresji gzip dla statycznych plików tekstowych (m.in. skrypty i style css) – dzięki temu można ograniczyć generowany transfer. Aby to zrobić, należy dodać do pliku .htaccess poniższe linijki. Możesz je dodać na jego końcu:

FileETag none

<IfModule mod_deflate.c>
# Insert filters
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/atom+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/x-httpd-php-source
AddOutputFilterByType DEFLATE image/svg+xml

<IfModule mod_setenvif.c>
# Drop problematic browsers
# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don't compress images
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
<IfModule mod_headers.c>
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
</IfModule>

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html A1
ExpiresByType application/xhtml+xml A1
# Add Expire header set to 30 days (far future)
ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000
ExpiresByType application/javascript A2592000
ExpiresByType application/x-javascript A2592000
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType image/vnd.microsoft.icon A2592000
ExpiresByType image/svg+xml A2592000
ExpiresByType text/plain A2592000
# Add Expire header set to 1 day
ExpiresByType text/xml A108000
ExpiresByType application/x-httpd-php A108000
ExpiresByType application/x-httpd-fastphp A108000
ExpiresByType application/x-httpd-php-source A108000
# Add Expire header set to 1 hour
ExpiresByType application/xml A108000
ExpiresByType application/atom+xml A108000
ExpiresByType application/rss+xml A108000
</IfModule>

# Fallback - when there is no mod_expires, try to add far future expire headers using mod_headers
<IfModule !mod_expires.c>
<IfModule mod_headers.c>
<Files ~ "\.(gif|jpe?g|png|css|ico|js)$">
Header set Expires "Thu, 15 Apr 2020 20:00:00 GMT"
</Files>
</IfModule>
</IfModule>

Powyższe wpisy do .htaccess powstały w wyniku moich analiz stron internetowych dokonanych za pomocą pluginów YSlow i Page Speed do FireFox’a. Polecam je zainstalować i przeanalizować analizy stron za ich pomocą. Szczególnie polecam ten drugi – w trakcie analizy wykonuje on także optymalizację obrazków i skryptów, tak aby szybciej się ładowały.

Poza wymienionymi powyżej metodami można jeszcze skorzystać z możliwości optymalizacji konfiguracji serwerów WWW i baz danych. Wymaga do jednak dostępu do konfiguracji serwera, trzeba więc mieć coś więcej niż hosting współdzielony. Zainteresowanych odsyłam do Google – zapytanie wordpress performance zwraca wiele artykułów które poruszają m.in ten temat.

Update 12.08.2009: przez przypadek zauważyłem że po włączeniu DB Cache nie można dodawać tagów do wpisów. Zgłosiłem ten błąd autorowi pluginu. Do momentu aż on tego nie poprawi odradzam instalację DB Cache.

Update 21.02.2010: Ponieważ plugin DB Cache nie został poprawiony, początkiem września zeszłego roku zdecydowałem się na jego poprawienie we własnym zakresie i opublikowałem go jako DB Cache Reloaded. Dodałem więc linka do niego powyżej w tym wpisie. Uaktualniłem też reguły do dodania do .htaccess, zgodnie z tym co się dowiedziałem w międzyczasie.

Przeczytaj też mój kolejny wpis, gdzie piszę dlaczego favikonka jest bardzo ważna.