Na pewno każdy, kto stworzył już co najmniej kilka stron na WordPressie, musiał zmierzyć się z tym problemem: strona na lokalnym lub testowym serwerze działała dobrze, a po udostępnieniu jej szerszej publiczności okazała się po prostu wolna. Jeśli najprostsze metody na poprawę wydajności nie zdały egzaminu, a zastosowanie cache również nie do końca pomaga (cache musi się w końcu raz na jakiś czas odbudować), to pora na znalezienie elementu strony, który odpowiada za nasze problemy z wydajnością. Oczywiście najlepiej jest wykonać takie rozeznanie jeszcze na etapie budowy serwisu, ale nie zawsze da się to zrobić (na przykład gdy nie dysponujemy taką ilością danych, jaka będzie znajdować się w finalnej wersji strony).
Narzędzi, które mogą pomóc w poszukiwaniu przyczyn problemu, jest sporo, ale jednym z moich ulubionych jest darmowa wtyczka Query Monitor, która szczegółowo pokazuje co dzieje się „pod maską” naszego serwisu.
Query Monitor służy nie tylko do identyfikacji problemów związanych z wydajnością, ale osobiście wykorzystuję ją głównie właśnie do tego celu i na tym skupię się w dalszej części wpisu. Jak łatwo zauważyć, zwracam uwagę głównie na zapytania do bazy danych, a to dlatego, że w znacznej większości przypadków to właśnie one są przyczyną wolnego działania strony.
Po instalacji i aktywacji wtyczki na górnym pasku narzędzi pojawi się dodatkowa sekcja, która zawiera cztery tajemniczo wyglądające ciągi znaków (widoczne u góry zamieszczonego obok zrzutu ekranu). Pierwszy z nich pokazuje całkowity czas generowania strony, wyrażony w sekundach. Drugi to maksymalna ilość pamięci, jaką nasz WordPress zarezerwował w trakcie generowania strony. Trzeci pokazuje sumaryczny czas wykonania wszystkich zapytań do bazy danych, a czwarty to liczba tych zapytań.
W tym momencie nasuwa się pytanie: jakie wartości tych parametrów powinny budzić niepokój, a jakie są całkowicie normalne? Na to pytanie nie ma niestety prostej i jednoznacznej odpowiedzi, bo wszystko zależy od wielu czynników. Jedno zapytanie SQL potrafi przy odpowiednio dużym ruchu „dobić” serwer. Z drugiej strony, kilkadziesiąt szybkich zapytań może nie sprawiać żadnego problemu.
Zasady typu „100 zapytań na stronę to maksimum” są zdecydowanie zbyt daleko idącym uproszczeniem sprawy, aczkolwiek nie twierdzę, że są całkowicie pozbawione sensu.
Na szczęście Query Monitor podaje bardzo dużo dodatkowych informacji, które mogą pomóc nam w zlokalizowaniu tych elementów naszej strony, które są przyczyną problemów z wydajnością serwisu.
Widoczna na zamieszczonym powyżej obrazku lista sekcji może nieco przytłaczać, ale nas tak naprawdę interesuje tylko kilka znajdujących się na niej pozycji.
Jedną z najważniejszych jest sekcja Slow Queries. Zawiera ona informacje o wykonujących się zbyt długo (czyli powyżej 0,05 sekundy) zapytaniach.
W kolumnie Component znajdziemy informację o komponencie, który wykonał dane zapytanie. Core to sam WordPress, Parent Theme to motyw główny, a Child Theme to motyw potomny. Na liście znajdują się również wtyczki, dzięki czemu bardzo łatwo możemy zidentyfikować (i w razie potrzeby wyłączyć) problematyczne rozszerzenie.
Kłopot pojawia się, gdy problematyczne zapytanie znajduje się w komponencie Core. Taki właśnie przypadek widać na zamieszczonym wyżej zrzucie ekranu. Jak nietrudno zauważyć, wolne (bo wykonujące się ponad 0,1 sekundy) zapytanie pobiera wszystkie rekordy z tabeli wp_options
. Niestety, nie jesteśmy w stanie z tym wiele zrobić, ponieważ tabela ta zawiera wszystkie ustawienia WordPressa, wtyczek i motywów.
Muszę jednak uczciwie przyznać, że ten przykład jest nietypowy. W kolumnie Affected Rows widać liczbę zwróconych przez zapytanie rekordów, która wynosi 1497 – żadna normalna strona nie ma tylu danych w tabeli wp_options
. To, co widać na obrazku, to dane z mojej testowej instalacji WordPressa, przez którą przewinęło się kilkaset wtyczek i kilkadziesiąt motywów.
Jeśli jednak jakimś cudem trafimy na taki przypadek, to jedynym wyjściem jest odchudzenie tabeli wp_options
przez usunięcie z niej zbędnych rekordów, co nie jest niestety prostym zadaniem.
Warto dodać, że na wolne zapytania SQL w WordPressie możemy trafić jeszcze w kilku sytuacjach, na przykład przy wpisach posiadających bardzo dużą liczbę komentarzy lub przy pobieraniu wpisów według skomplikowanych warunków.
Zobaczmy więc trochę bardziej życiowy przykład, w którym dzięki Query Monitor uzyskamy przydatne informacje i bez większego trudu będziemy w stanie wyeliminować przyczynę problemów z wydajnością naszej strony.
Na powyższym zrzucie ekranu widzimy drugą bardzo przydatną sekcję wtyczki – Queries by Component. Zawiera ona liczbę zapytań (z podziałem na ich rodzaj – SELECT, INSERT, DELETE, UPDATE, SHOW) wraz z łącznym czasem ich wykonania. Są to po prostu zsumowane dane z sekcji Queries, pogrupowane według komponentu. Jak widać na przykładzie, wtyczka Widget Visibility wykonała ponad 100 zapytań SQL, które łącznie trwały prawie 0,13 sekundy. Pozornie to nie dużo, ale pamiętajmy, że to tylko jeden z elementów strony, na dodatek wcale nie największy ani najważniejszy.
Warto zauważyć, że wtyczka ta nie pojawiła się w sekcji Slow Queries, ponieważ żadne z ponad stu wykonanych przez nią zapytań nie trwało dłużej, niż 0,05 sekundy. Sumarycznie jednak to właśnie ona zajęła bazie danych najwięcej czasu.
Wiemy już co obciąża naszą stronę – pora więc na rozwiązanie problemu. Z grubsza rzecz ujmując, mamy trzy wyjścia. Możemy po prostu wyłączyć problematyczną wtyczkę i (jeśli to konieczne) poszukać dla niej zamiennika. Możemy zastosować mechanizm cache, który w sporej części przypadków (ale nie zawsze) załatwi sprawę. Możemy również spróbować poprawić wtyczkę, co jednak wymaga wiedzy technicznej i nie zawsze jest możliwe (czasem jedynym wyjściem jest napisanie jej od nowa).
W niektórych (nie oszukujmy się – nielicznych) przypadkach możemy nieco poprawić wydajność zapytań SQL poprzez zrobienie porządków w bazie danych. Mniejsza ilość danych w połączeniu z przebudowaniem indeksów po usunięciu zbędnych rekordów z bazy nie zdziała wprawdzie cudów, ale na pewno nie zaszkodzi. Do takiego sprzątania można skorzystać z wtyczek WP-Sweep lub WP-Optimize – pierwszą z nich opisywałem już na WPzen.
Na marginesie dodam, że wspomniana wtyczka Widget Visibility w specyficznych przypadkach potrafi wykonać na jednej podstronie nawet kilkaset zapytań do bazy danych, które w sumie mogą trwać nawet kilka sekund i skutecznie obciążyć nasz serwer. Zdecydowanie odradzam korzystanie z tej wtyczki.
Query Monitor posiada jeszcze jedną interesującą z punktu widzenia szybkości działania strony sekcję – HTTP Requests. Pokazuje ona wszystkie wykonane żądania HTTP, najczęściej związane z komunikacją z zewnętrznymi usługami.
Na przykładzie widać żądanie wykonane przez wbudowany w WordPressa mechanizm automatycznych aktualizacji. Sekcja ta pokaże nam również wszystkie żądania wysyłane przez używane przez nas wtyczki i motyw. I tu czasami pojawiają się problemy. Autorzy rozszerzeń (dotyczy to praktycznie tylko produktów spoza oficjalnego repozytorium) często implementują własne mechanizmy aktualizacji lub pobierania danych z zewnętrznych źródeł (na przykład listy fontów z Google Fonts czy wpisów z serwisów społecznościowych). Mechanizmy te mogą działać nieprawidłowo, a usługi, z którymi się łączą, mogą być chwilowo lub całkowicie niedostępne. W obu przypadkach może się zdarzyć, że zanim strona się załaduje będziemy musieli poczekać na zakończenie takiego żądania – a to (zależnie od wartości parametru timeout) może trwać od kilku do kilkudziesięciu sekund. Takie problematyczne żądanie pojawi się w sekcji HTTP Requests wraz z informacją o pliku i numerze linii, w której zostało ono zainicjowane – dzięki temu możemy łatwo je odnaleźć i poprawić lub usunąć (albo po prostu przekazać odpowiednią informację autorowi).
Warto dodać, że sekcja HTTP Requests zawiera tylko żądania wykonane za pomocą HTTP API.
Zdaję sobie sprawę, że wpis ten może pozostawiać lekki niedosyt: pokazałem jak znaleźć przyczynę problemów, ale nie pokazałem jak ją usunąć. Rzecz w tym, że nie ma uniwersalnej metody i do każdego przypadku trzeba podejść indywidualnie. Jeśli problemem jest konkretna wtyczka (a dzięki Query Monitor już wiecie jak ją zidentyfikować), to trzeba się jej po prostu pozbyć – nie wiadomo jakie jeszcze niespodzianki przed nami kryje, a ta metoda rozwiązania problemu jest najszybsza i najskuteczniejsza. Gdy jednak za naszymi problemami z wydajnością stoi sam WordPress, to będziemy potrzebować wiedzy i doświadczenia, aby znaleźć odpowiednie rozwiązanie.