WordPress – przyspieszanie szablonu „Engine” od Industrial Themes.

Świetna skórka, kiepskie wykonanie

W dzisiejszym wpisie przyjrzymy się szablonowi Engine. Dlaczego? Ponieważ jest zrobiony bardzo źle. Tak źle, że na wygenerowanie strony na serwerze trzeba czekać ponad 6 sekund. Na tym samym serwerze drugi WordPress potrzebuje 0,5 sekundy. Tak więc ewidentnie coś jest nie tak. Wtyczki od razu wykluczyłem, ponieważ w obydwu serwisach wgrane są identyczne, więc jedyną rzeczą jaka może powodować spowolnienie jest szablon.

Na początek zobaczmy jak wygląda zrzut xdebuga ze strony głównej (134MB):

xdebugPo lewej stronie mamy sortowanie domyślne, po prawej sortowanie czasem danej funkcji. Jak widać, najwięcej energii strona poświęca na wykonywanie polecenia unserialize (wywoływane 3506 razy). Jest to systemowa funkcja, więc niewiele na to poradzimy, ale możemy zastanowić się nad pewną kwestią. Dlaczego unserialize wywoływane jest ponad 3.5 tysiąca razy? Druga w kolejce jest funkcja it_get_setting, która ma prawie 2400 wywołań. Wygląda na to, że jest to dość dobry punkt zaczepienia. Zobaczmy jaki jest kod tej funkcji (od razu wyjaśnią się pozostałe czerwone obramowania):


if(!function_exists('it_get_setting')) {
#get theme options
function it_get_setting( $option = '' ) {
$settings = '';

if ( !$option )
return false;

$settings = str_replace('\"', '"', get_option( IT_SETTINGS ));
$settings = str_replace("\'", "'", $settings);

if( !empty( $settings[$option] ) )
return $settings[$option];

return false;
}
}

Widzimy, że powyższa funkcja wywołuje get_option (w całym skrypcie 4016 razy) oraz dwa razy str_replace (w całym skrypcie 11073 razy). Funkcja nie pamięta pobranych danych, więc za każdym razem musi wykonać przynajmniej te dwa str_replace. Natomiast co do get_option, to jest to funkcja wbudowana w WordPressa. Jej treść możemy zobaczyć na stronie https://developer.wordpress.org/reference/functions/get_option/#source (trzeba kliknąć na „expand full source code”). Widzimy, że wywoływane jest apply_filters oraz wp_cache*. Czyli to, co zaznaczyłem na obrazku. Spróbujmy zatem coś na to poradzić. Na początek wstawimy zmienną globalną, która przechowa wyciągnięte ustawienia.

if(!function_exists('it_get_setting')) {
#get theme options
function it_get_setting( $option = '' ) {
global $moje_it_setting ; 
$settings = '';

if ( !$option )
return false;

if( !empty( $moje_it_setting )) return $moje_it_setting[$option] ;
$settings = str_replace('\"', '"', get_option( IT_SETTINGS ));
$settings = str_replace("\'", "'", $settings);

$moje_it_setting = $settings ; 
if( !empty( $settings[$option] ) )
return $settings[$option];

return false;
}
} 

Dodaliśmy do funkcji zmienną $moje_it_setting, która przechowuje ustawienia przez cały czas działania skryptu. Jeśli dobrze trafiliśmy, to liczba wywołań get_option spadnie o ponad 2300, a liczba wywołań str_replace o ponad 4600. Zróbmy jeszcze raz zrzut przy pomocy xdebuga i zobaczmy rezultat.

xdebug2Jak widać wpisy związane z it_get_setting zniknęły z listy (bądź przesunęły się na niższe pozycje). Liczba wywołań get_option oraz unserialize wynosi odpowiednio: 1497 oraz 1047 (przed zmianami: 4016 oraz 3506). Co na to sama strona? Do wygenerowania potrzeba obecnie 1.5 sekundy. Nie jest to jakaś oszałamiająca wielkość i z całą pewnością da się urwać jeszcze co najmniej połowę. Na obrazku zaznaczyłem elementy, które także da się przyspieszyć w dość prosty sposób. WordPress korzysta z dość skomplikowanego mechanizmu jeśli chodzi o tłumaczenia. Sam czyta pliki *.mo i aktywuje tłumaczenia dla wskazanych fragmentów szablonu i wtyczek. Przy pomocy wtyczki „WP Performance Pack” możemy włączyć czysty gettext (o ile serwer na to zezwoli) i ograniczyć czas potrzebny do załadowania plików z tłumaczeniami. Uwaga! Przyspieszenie będzie widoczne (a nie iluzoryczne) w przypadku serwisu z dużą ilością tłumaczonych wtyczek. Na dodatek wtyczki te muszą mieć „spuchnięte” tłumaczenia. Takimi wtyczkami są np. woocommerce, bbpress, buddypress itd.

Dopisek 1

Po zagłębieniu się w pliki odnaleźć możemy kolejną rzecz wartą poprawienia. Jest to mianowicie plik loop.php, który odpowiada za wyświetlenie wszystkich grup postów (czy to z widgetów, czy umieszczonych bezpośrednio w centralnej kolumnie). Po otwarciu pliku w nasze oczy rzuci się duża ilość wywołań get_the_ID(). Tak jest. Dla każdego posta z listy do wyświetlenia wywoływanych jest 40 czy 50 funkcji pobierania id posta. Czy ma to sens? Jak najbardziej nie. Sprawę załatwiamy w następujący sposób:


if ($itposts->have_posts()) : while ($itposts->have_posts()) : $itposts->the_post(); $p++;
global $post ;

(dodana linijka global $post;). Od tej chwili mamy dostęp do danych wygenerowanych przez the_post(). Odpalamy więc podmianę tekstu i wpisujemy jako szukane get_the_ID(), a jako do wstawienia dajemy $post->ID. Zaoszczędzimy dzięki temu trochę czasu dzięki pozbyciu się niepotrzebnych wywołań. Poprawić możemy jeszcze has_post_thumbnail (wystarczy przecież odwołać się za drugim razem do $cssimage).

Jeśli coś jeszcze znajdę wartego poprawienia, to uzupełnię ten wpis o stosowną adnotację.

Dodaj komentarz

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

*