Ograniczanie liczby wywołań php na stronie

Przez kilka ostatnich dni starałem się poprawić wydajność w serwisie stojącym na WordPressie. Problemem była nie tylko spora liczba zapytań do bazy (nadal są podstrony, które generują po 100 na wyświetlenie), ale także (między innymi) duża ilość obrazków generowanych poprzez timthumb. Wydawać by się mogło, że nie będzie to problemem, ponieważ timthumb ma możliwość odsyłania wcześniej wygenerowanych miniatur (więc gd nie jest używane), ale każde takie wywołanie wymuszało na serwerze ciągłe przetwarzanie tego skryptu php.  To samo tyczyło się skryptów js oraz styli css, które zapisane były jako php, dzięki czemu można było przekazać do nich parametry i w ten sposób wpłynąć na wyświetlanie strony. Wszystko było już ustawione, więc nie było powodu, żeby php ciągle generowało skrypty i style. Wystarczyło kilka modyfikacji, żeby statyczne pliki zaczęły być prawdziwie statycznymi plikami, a serwer przestał się dławić od liczby przetwarzanych skryptów php. Ale po kolei.

style.php, lytebox.js.php

Te pliki wymagają najmniejszej ingerencji. Przy pomocy podglądu źródła strony w Firefoxie (bądź po otwarciu wywołania z listy Firebuga, narzędzi deweloperskich Chrome) przechodzimy do treści tych plików. Kopiujemy całość, a następnie na serwerze tworzymy odpowiedniki: style.css, lytebox.js, itd. Na koniec podmieniamy adresy do tych plików w szablonach, wtyczkach, czy gdzie one zostały wstawione. Oczywiście zmiana spowoduje utrudnienia w późniejszych modyfikacjach wyglądu strony. Niestety, coś za coś.

thumb.php, timthumb.php, foto.php

Z generatorem miniatur będzie trochę ciężej. Po pierwsze należy się upewnić, że jest on w stanie generować miniatury i zapisywać je na dysku, np: imagejpeg($canvas, $tempfile, $quality); Jeżeli tak, to należy zadbać o to, żeby zamiast odwołania bezpośrednio do generatora było wstawione odwołanie do wcześniej stworzonej miniatury. W przypadku serwisu działającego na Smarty posłużyć się można odpowiednią wtyczką:


<? 
function smarty_function_foto( $params, &$smarty ) {
  $id = $params['id'] + 0;
  if( file_exists( 'img/cache/'.$id.'.jpg' )) {
    return 'img/cache/'.$id.'.jpg' ;
  }
  else
    return 'foto.php?id='.$id ;
}
?>

Można także całkowicie pominąć foto.php i wstawić generowanie miniatury oraz odesłanie bezpośredniego adresu do niej:

else {
 generuj_miniature( $params ) ;
 return 'img/cache/'.$id.'.jpg' ; 
}

W ten sposób nikt (ani bot, ani człowiek) nie będzie wywoływać naszego generatora miniatur. Podmiana miniatury będzie wymagać skasowania odpowiedniego pliku, a jeśli nowe obrazki dostają zupełnie inny numer id, to i o to nie będziemy musieli się martwić. Dla zachowania porządku na dysku zalecane jednak będzie skasowanie miniatury wraz z oryginałem, ale to już leży po stronie admina, a nie generatora miniatur.

W przypadku WordPressa i WooThemes modyfikujemy plik functions/admin-functions.php znajdujący się w obecnie używanym przez nas szablonie, a dokładniej zmieniamy funkcję woo_get_image. Możemy zmodyfikować ją tak jak w przypadku Smarty, ale jeśli mamy na serwerze zainstalowanego Varnisha, to możemy pokusić się o stworzenie odpowiedniej ścieżki do obrazka, dzięki czemu Varnish potraktuje wywołanie jako dostępne do przechowania.

Tak może wyglądać zmodyfikowana linijka:


$img_link = '<img src="'. get_bloginfo('url'). '/resize/'.$width.'x'.$height.'/r'. $url_obrazka.'" 
alt="'. get_the_title($id) .'" '. $set_height . $set_width . ' />';

($url_obrazka to zmienna zawierająca lokalne położenie, np. wp-content/upload/obrazek.jpg). Woo_get_image ma odwołanie do $img_link w kilku miejscach, więc warto podmienić wszystkie na raz, tak dla świętego spokoju.

Do pliku .htaccess natomiast wstawiamy dwie linijki (powyżej wordpressowego przechwytywacza wywołań):


RewriteCond %{REQUEST_URI} ^/(resize) [NC]
RewriteRule ^resize/(.*)x(.*)/r/(.*)  wp-content/themes/layout/timthumb.php?src=http://adres_strony/$3&h=$2&w=$1&c=1 [L]

W ten sposób Varnish będzie otrzymywać „przyjazne” linki, a wskaźnik Hitrate avg powinien osiągnąć wyższą wartość.

Podsumowanie

Po wycięciu ze strony wszystkich obrazków, styli i skryptów js generowanych przez php powinniśmy otrzymać szybciej działającą stronę oraz mniejsze obciążenie na serwerze. Ograniczenie występowania generatora miniatur także powinno mieć zbawienny wpływ. Jeśli jest to wersja bez cache, to warto ją wprowadzić. Dzięki temu tylko raz będzie potrzebne przetworzenie grafiki. Do rozważenia jeszcze pozostała opcja generowania miniatur bezpośrednio z admina, ale jest to rozwiązanie połowiczne. W razie przebudowy strony i zmiany wielkości obrazków konieczne będzie wygenerowanie na nowo wszystkich miniatur.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

*