Przejdź do treści

Jak przyspieszyć WordPressa? 15 rzeczy, których PageSpeed Insights Ci nie pokaże

autor: Jacek Sultan Bezpieczeństwo i wydajność 16 minut czytania

PageSpeed pokazuje wynik, ale nie pokaże Ci źle napisanego WP_Query, ciężkiego meta_query, zapchanego autoloadu czy API odpytywanego przy każdym wejściu. Zobacz 15 rzeczy, które warto sprawdzić w kodzie i konfiguracji WordPressa, gdy strona naprawdę działa wolno.

PageSpeed Insights pokazuje, że strona jest wolna. Nie zawsze pokazuje jednak, dlaczego.

Możesz skompresować obrazy, włączyć cache, zminimalizować CSS i nadal mieć WordPressa, który przy każdym wejściu wykonuje kilkadziesiąt niepotrzebnych zapytań do bazy, czeka na zewnętrzne API albo przetwarza tę samą treść od początku.

Dlatego przy optymalizacji WordPressa nie zaczynamy od próby zdobycia 100 punktów w PageSpeed. Najpierw sprawdzamy, gdzie aplikacja rzeczywiście traci czas.

Poniżej zebrałem 15 rzeczy, które warto sprawdzić w kodzie i konfiguracji WordPressa. To problemy, które regularnie pojawiają się w istniejących stronach i sklepach, a część z nich można znaleźć i poprawić w kilkanaście minut.

Najpierw: PageSpeed Insights nie pokazuje całego obrazu

Zanim zaczniemy grzebać w kodzie, trzeba rozróżnić dwie rzeczy, które PageSpeed Insights pokazuje w jednym raporcie.

Dane laboratoryjne pochodzą z Lighthouse. To test wykonany w kontrolowanych warunkach na emulowanym urządzeniu i połączeniu.

Dane rzeczywistych użytkowników pochodzą z Chrome UX Report i obejmują okres ostatnich 28 dni. To właśnie tutaj znajdziesz Core Web Vitals: LCP, INP i CLS.

Możesz więc mieć 90 punktów w Lighthouse i nadal mieć problem z INP u prawdziwych użytkowników. Możliwa jest również odwrotna sytuacja: wynik laboratoryjny wygląda przeciętnie, ale rzeczywiste dane użytkowników są dobre.

Dlatego liczba w kolorowym kółku nie powinna być głównym celem optymalizacji.

1. Sprawdź, czy nie pobierasz tych samych pól ACF wiele razy

To bardzo prosty przykład, ale dobrze pokazuje sposób myślenia przy optymalizacji backendu.

W szablonie możesz znaleźć coś takiego:

php
$title = get_field('title');
$price = get_field('price');
$image = get_field('image');

Jeżeli potrzebujesz wielu pól tego samego obiektu, warto sprawdzić, czy nie można pobrać ich razem:

php
$fields = get_fields();

$title = $fields['title'];
$price = $fields['price'];
$image = $fields['image'];

Nie chodzi o mechaniczne zastępowanie każdego get_field(). ACF i WordPress korzystają z własnych mechanizmów cache, więc nie każde kolejne wywołanie oznacza nowe zapytanie SQL.

Warto natomiast zwrócić uwagę na kod, który wielokrotnie pobiera i przetwarza te same dane. Szczególnie jeśli dzieje się to wewnątrz pętli.

2. Nie odpytuj zewnętrznego API przy każdym wejściu

Jednym z najłatwiejszych sposobów na bardzo niestabilny TTFB jest uzależnienie renderowania strony od zewnętrznego API.

Przykład:

php
$data = file_get_contents('https://api.example.com/data');
$data = json_decode($data, true);

Każdy użytkownik musi teraz czekać nie tylko na Twój serwer, ale również na odpowiedź drugiego systemu.

Jeżeli API odpowie w 100 ms, może być dobrze. Jeżeli odpowie w dwie sekundy, Twoja strona również czeka. Jeżeli przestanie odpowiadać, sytuacja robi się jeszcze gorsza.

Jeśli dane nie muszą być aktualne co sekundę, zapisz je w cache:

php
$data = get_transient('crm_data');

if ($data === false) {
    $response = wp_remote_get('https://api.example.com/data');

    if (!is_wp_error($response)) {
        $data = json_decode(
            wp_remote_retrieve_body($response),
            true
        );

        set_transient(
            'crm_data',
            $data,
            15 * MINUTE_IN_SECONDS
        );
    }
}

Zewnętrzny system jest wtedy odpytywany raz na określony czas, a nie przy każdym wejściu użytkownika.

Przy bardziej krytycznych integracjach poszedłbym jeszcze dalej: synchronizacja powinna odbywać się w tle, a frontend powinien czytać dane, które znajdują się już lokalnie.

3. Uważaj na operacje na plikach wykonywane przy każdym requeście

Odczytywanie i parsowanie pliku za każdym razem, gdy WordPress generuje stronę, również potrafi niepotrzebnie zwiększać koszt requestu.

php
if (file_exists(get_template_directory() . '/config.json')) {
    $config = json_decode(
        file_get_contents(
            get_template_directory() . '/config.json'
        ),
        true
    );
}

Jeżeli te same dane są potrzebne kilka razy podczas jednego requestu, można przynajmniej zatrzymać wynik w pamięci:

php
function get_config() {
    static $config = null;

    if ($config === null) {
        $config = json_decode(
            file_get_contents(
                get_template_directory() . '/config.json'
            ),
            true
        );
    }

    return $config;
}

Jeżeli konfiguracja zmienia się rzadko, można pójść dalej i wykorzystać cache trwały albo przetworzyć ją wcześniej.

4. Dodaj no_found_rows tam, gdzie nie potrzebujesz paginacji

Własne zapytania WP_Query to jedno z pierwszych miejsc, które sprawdzamy na wolnej stronie.

Typowy fragment wygląda tak:

php
$query = new WP_Query([
    'post_type'      => 'post',
    'posts_per_page' => 6,
]);

Jeżeli wyświetlasz po prostu sześć ostatnich wpisów i nie potrzebujesz informacji o całkowitej liczbie wyników ani paginacji, dodaj:

php
$query = new WP_Query([
    'post_type'      => 'post',
    'posts_per_page' => 6,
    'no_found_rows'  => true,
]);

WordPress nie musi wtedy wykonywać dodatkowej pracy potrzebnej do policzenia pełnej liczby wyników.

Na pojedynczym zapytaniu różnica może być mała. Jeśli takich komponentów jest kilka, baza jest duża, a strona obsługuje dużo requestów, małe koszty zaczynają się sumować.

5. Jeśli potrzebujesz tylko ID, nie pobieraj całych obiektów

Podobna zasada dotyczy danych zwracanych przez WP_Query.

Jeżeli potrzebujesz wyłącznie identyfikatorów produktów, nie zawsze ma sens pobieranie pełnych obiektów WP_Post.

php
$query = new WP_Query([
    'post_type' => 'product',
]);

Możesz ograniczyć wynik:

php
$query = new WP_Query([
    'post_type' => 'product',
    'fields'    => 'ids',
]);

To szczególnie istotne przy większych zbiorach i operacjach wykonywanych w tle.

6. Szukaj posts_per_page ustawionego na -1

posts_per_page => -1 jest wygodne, bo oznacza: pobierz wszystko.

I właśnie dlatego potrafi być niebezpieczne.

php
$query = new WP_Query([
    'post_type'      => 'product',
    'posts_per_page' => -1,
]);

Przy 40 rekordach nic się nie stanie. Przy 40 000 sytuacja wygląda zupełnie inaczej.

Jeżeli nie potrzebujesz całego zbioru jednocześnie, wprowadź limit i paginację:

php
$query = new WP_Query([
    'post_type'      => 'product',
    'posts_per_page' => 12,
]);

W istniejącym projekcie warto po prostu przeszukać kod pod kątem posts_per_page i sprawdzić każde miejsce z wartością -1.

7. Meta query potrafi stać się wąskim gardłem

WordPress pozwala bardzo łatwo filtrować wpisy po metadanych:

php
'meta_query' => [
    [
        'key'     => 'price',
        'value'   => 100,
        'compare' => '>',
        'type'    => 'NUMERIC',
    ],
]

To wygodne rozwiązanie, ale przy dużych zbiorach wp_postmeta może stać się jednym z najcięższych elementów całej aplikacji.

Jeżeli na metadanych budujesz intensywnie używane filtrowanie, sortowanie albo raportowanie, warto sprawdzić rzeczywiste zapytania w Query Monitorze i przeanalizować je przez EXPLAIN.

sql
EXPLAIN
SELECT ...
FROM wp_posts
INNER JOIN wp_postmeta
    ON wp_posts.ID = wp_postmeta.post_id
WHERE ...;

W zależności od rodzaju danych lepszym rozwiązaniem może być taksonomia, dodatkowe indeksy albo osobna tabela zaprojektowana pod konkretny sposób wyszukiwania.

Nie ma sensu przepisywać każdego meta_query. Problem zaczyna się wtedy, gdy traktujemy wp_postmeta jak uniwersalną bazę do dowolnego rodzaju zapytań na dużej liczbie rekordów.

8. Włącz persistent object cache tam, gdzie ma sens

WordPress ma mechanizm Object Cache, ale bez dodatkowego backendu dane nie są zachowywane pomiędzy kolejnymi requestami.

Przy większych serwisach i WooCommerce warto sprawdzić Redis lub Memcached.

Najprościej zacząć od Query Monitora i zobaczyć, czy persistent object cache jest aktywny oraz ile zapytań wykonuje konkretna podstrona.

Redis nie naprawi źle napisanego zapytania ani kodu pobierającego tysiące rekordów. Może jednak bardzo dobrze ograniczyć koszt danych, które WordPress pobiera wielokrotnie.

9. Sprawdź autoload w wp_options

To jedna z rzeczy, które potrafią narastać przez lata razem z instalowaniem i usuwaniem kolejnych wtyczek.

Opcje oznaczone jako autoload są ładowane automatycznie podczas działania WordPressa. Jeżeli trafiają tam duże struktury danych, płacisz za nie przy ogromnej liczbie requestów, nawet jeśli konkretna podstrona ich nie potrzebuje.

Warto zacząć od sprawdzenia największych wpisów:

sql
SELECT
    option_name,
    LENGTH(option_value) AS size
FROM wp_options
WHERE autoload IN ('yes', 'on', 'auto-on', 'auto')
ORDER BY size DESC
LIMIT 50;

Nie wyłączaj jednak autoloadu mechanicznie dla wszystkiego, co jest duże.

Najpierw ustal, do czego należy dana opcja, czy jest nadal używana i jak często aplikacja jej potrzebuje. Dopiero wtedy można zdecydować, czy powinna być ładowana automatycznie.

10. Sprawdź, co korzysta z admin-ajax.php

Starsze wtyczki i motywy bardzo często realizują komunikację z backendem przez:

js
fetch('/wp-admin/admin-ajax.php', {
    method: 'POST',
    body: data
});

Samo użycie admin-ajax.php nie jest błędem. Problem pojawia się wtedy, gdy frontend odpytuje go często albo wykorzystuje do prostych operacji, które można zrealizować inaczej.

W DevTools otwórz zakładkę Network, wpisz admin-ajax.php w filtrze i używaj strony przez chwilę.

Jeżeli request pojawia się co kilka sekund bez wyraźnej potrzeby albo każda drobna interakcja użytkownika generuje kolejne wywołanie, warto sprawdzić jego źródło.

Dla własnych endpointów można wykorzystać WordPress REST API:

js
fetch('/wp-json/custom/v1/data')
    .then(response => response.json())
    .then(data => {
        console.log(data);
    });

Najważniejsza nie jest jednak sama zamiana jednego adresu na drugi. Trzeba sprawdzić, co endpoint wykonuje, jak często jest wywoływany i czy odpowiedź można cache'ować.

11. Cache'uj wynik ciężkich obliczeń, a nie tylko strony

Cache strony jest świetny, dopóki użytkownik może dostać gotowy HTML.

Nie rozwiązuje jednak każdego przypadku. WooCommerce, zalogowani użytkownicy, API i dynamiczne fragmenty aplikacji nadal mogą wykonywać kosztowne operacje.

Załóżmy, że przygotowanie danych wymaga pobrania produktów, przeliczenia ich i posortowania:

php
usort($products, function ($a, $b) {
    return $a['price']  $b['price'];
});

Jeżeli wynik nie zmienia się przy każdym requeście, możesz zapisać gotowe dane:

php
$products = get_transient('sorted_products');

if ($products === false) {
    $products = get_products();

    usort($products, function ($a, $b) {
        return $a['price']  $b['price'];
    });

    set_transient(
        'sorted_products',
        $products,
        HOUR_IN_SECONDS
    );
}

Zasada jest prosta: jeśli wykonujesz kosztowną operację setki razy na tych samych danych, sprawdź, czy naprawdę musi być wykonywana setki razy.

12. Wyprowadź WP-Cron z requestów użytkowników

Domyślny WP-Cron nie jest klasycznym cronem systemowym. WordPress sprawdza zadania przy ruchu na stronie.

Przy prostym blogu często nie ma to większego znaczenia. W WooCommerce albo rozbudowanym systemie liczba zadań potrafi jednak znacząco wzrosnąć.

Efektem mogą być requesty, które raz odpowiadają szybko, a innym razem nagle wykonują dodatkową pracę.

Możesz wyłączyć standardowe uruchamianie WP-Cron:

php
define('DISABLE_WP_CRON', true);

A następnie uruchamiać zadania z prawdziwego schedulera:

bash
*/5 * * * * wp cron event run --due-now --path=/var/www/html > /dev/null 2>&1

Jeżeli WordPress działa w kontenerach, cron może mieć własny worker:

yaml
cron:
  image: wordpress:cli
  volumes:
    - ./:/var/www/html
  entrypoint: >
    sh -c "while true; do
      wp cron event run --due-now --path=/var/www/html;
      sleep 300;
    done"

Dzięki temu wykonanie zadań nie zależy od tego, czy ktoś właśnie otworzył stronę, a logowanie i diagnozowanie problemów jest prostsze.

13. Nie parsuj całego HTML przy każdym wyświetleniu strony

To jeden z ciekawszych problemów, bo na pierwszy rzut oka kod może wyglądać całkiem niewinnie.

php
add_filter('the_content', function ($content) {
    $dom = new DOMDocument();
    @$dom->loadHTML($content);

    // manipulacje na HTML


    return $dom->saveHTML();
});

Teraz każde wyświetlenie wpisu może uruchamiać parser HTML, budować strukturę DOM, modyfikować ją i ponownie serializować.

Jeżeli efekt zależy wyłącznie od treści wpisu, znacznie lepszym miejscem na ciężką pracę może być moment zapisu:

php
add_action('save_post', function ($post_id) {
    $content = get_post_field(
        'post_content',
        $post_id
    );

    $dom = new DOMDocument();
    @$dom->loadHTML($content);

    // manipulacje na HTML


    $processed = $dom->saveHTML();

    update_post_meta(
        $post_id,
        '_processed_content',
        $processed
    );
});

Frontend pobiera wtedy gotowy wynik:

php
echo get_post_meta(
    get_the_ID(),
    '_processed_content',
    true
);

To jedna z ważniejszych zasad optymalizacji aplikacji: jeżeli coś można policzyć raz podczas zapisu, nie licz tego ponownie przy każdym odczycie.

14. Sprawdź ciężką logikę podpiętą do globalnych hooków

init, wp i podobne hooki są wygodne, ale trzeba pamiętać, jak często się wykonują.

Taki kod:

php
add_action('init', function () {
    $data = expensive_operation();
});

może wykonywać ciężką operację przy ogromnej liczbie requestów, mimo że jej wynik potrzebny jest tylko w jednym miejscu.

Najpierw ogranicz zakres wykonania:

php
add_action('wp', function () {
    if (!is_page('oferta')) {
        return;
    }

    expensive_operation();
});

A jeszcze lepiej sprawdź, czy operacja musi być wykonywana podczas requestu użytkownika.

Jeżeli dane można przygotować podczas zapisu, przez cron albo po zmianie konkretnej opcji, frontend powinien dostać już gotowy wynik.

15. Nie ładuj CSS i JavaScriptu wszędzie

To klasyczny problem rozbudowanych instalacji WordPressa.

Formularz jest tylko na stronie kontaktowej, ale jego CSS i JavaScript trafiają na każdą podstronę. Slider działa na stronie głównej, ale jego biblioteka jest obecna również na blogu. Skrypt WooCommerce trafia tam, gdzie nie ma żadnej funkcji sklepowej.

Najpierw otwórz DevTools → Network i Query Monitor → Scripts & Styles.

Sprawdź, które zasoby pochodzą z wtyczek i czy rzeczywiście są potrzebne na aktualnej podstronie.

Dla własnego projektu można ładować assety warunkowo albo usuwać niepotrzebne z kolejki:

php
add_action('wp_enqueue_scripts', function () {
    if (!is_page('kontakt')) {
        wp_dequeue_style('contact-form-7');
        wp_dequeue_script('contact-form-7');
    }
}, 100);

Nie kopiuj jednak gotowej listy wp_dequeue_* z internetu.

Sprawdź zależności na swojej stronie i przetestuj funkcje po każdej zmianie. Wtyczka może wykorzystywać skrypt również w miejscu, którego na pierwszy rzut oka nie widać.

A gdzie obrazy, WebP, minifikacja i lazy loading?

Są ważne, ale to zwykle właśnie od nich zaczynają wszystkie poradniki.

Jeżeli obraz hero waży 4 MB, oczywiście trzeba go poprawić. Jeśli strona ładuje dziesięć odmian fontu, również warto się tym zająć.

Problem w tym, że można doprowadzić frontend do bardzo dobrego stanu i nadal czekać sekundę lub dwie, zanim serwer zacznie wysyłać HTML.

Dlatego patrzymy również na TTFB.

Jeżeli jest wysoki, sprawdzamy między innymi page cache, wersję PHP, zapytania do bazy, object cache, zewnętrzne API, cron oraz kod wykonywany przy każdym requeście.

Dopiero potem optymalizujemy to, co przeglądarka robi z otrzymanym dokumentem.

Sprawdź obraz LCP, zanim zainstalujesz kolejną wtyczkę do lazy loadingu

WordPress ma już własne mechanizmy optymalizujące ładowanie obrazów.

Problem pojawia się, kiedy dodatkowa wtyczka do lazy loadingu próbuje zrobić to jeszcze raz i opóźnia obraz, który użytkownik powinien zobaczyć jako pierwszy.

Otwórz kod wygenerowanej strony i znajdź główny obraz w pierwszej sekcji.

Jeżeli zobaczysz coś podobnego:

html
<img
    src="hero.webp"
    loading="lazy"
    alt="..."
>

sprawdź, czy właśnie ten obraz nie jest Twoim LCP.

Dla obrazu znajdującego się od razu w pierwszym widoku opóźnianie pobrania może pogorszyć wynik zamiast go poprawić.

W odpowiednim przypadku przeglądarka może dostać informację o wysokim priorytecie:

html
<img
    src="hero.webp"
    fetchpriority="high"
    alt="..."
>

Nie oznacza to, że należy dodać fetchpriority="high" do wszystkich obrazów. Priorytet przestaje mieć sens, jeżeli wszystko staje się priorytetem.

Najtrudniejszy problem WooCommerce często zaczyna się po załadowaniu strony

Sklep może otworzyć się szybko, a mimo tego sprawiać wrażenie ciężkiego.

Użytkownik wybiera wariant produktu, otwiera mini-koszyk, filtruje kategorię albo zmienia liczbę produktów i dopiero wtedy interfejs zaczyna się zacinać.

W tym momencie jednocześnie mogą działać skrypty motywu, WooCommerce, kilku dodatków, analityki, reklam, czatu i narzędzia do testów A/B.

To właśnie dlatego nie można oceniać wydajności sklepu wyłącznie na podstawie pierwszego załadowania strony.

W rzeczywistych danych odpowiada za to między innymi INP. Dobry wynik to maksymalnie 200 ms na 75. percentylu rzeczywistych wizyt.

Jeżeli PageSpeed pokazuje 90 punktów, ale użytkownik po kliknięciu „Dodaj do koszyka” przez sekundę nie widzi reakcji, problem nadal istnieje.

Jak diagnozujemy wolnego WordPressa

Nie zmieniamy piętnastu rzeczy jednocześnie, bo później nie wiadomo, która z nich faktycznie pomogła.

Zaczynamy od pomiaru TTFB i danych Core Web Vitals. Następnie sprawdzamy Query Monitor, liczbę i czas zapytań SQL, object cache, requesty HTTP wykonywane przez backend oraz zasoby ładowane przez przeglądarkę.

Przy podejrzeniu konkretnego fragmentu kodu używamy profilera. Przy wolnych zapytaniach sprawdzamy SQL i EXPLAIN. Przy problemach po stronie przeglądarki korzystamy z Performance i Network w DevTools.

Dopiero po znalezieniu wąskiego gardła zmieniamy kod.

Po zmianie wykonujemy ten sam pomiar ponownie.

To ważne, ponieważ „optymalizacja” wykonana bez pomiaru bardzo łatwo kończy się kolejną wtyczką, dodatkową warstwą cache i większą złożonością bez zauważalnej poprawy.

W jakiej kolejności optymalizować WordPressa?

Jeżeli mielibyśmy sprowadzić cały proces do jednej kolejności, wyglądałaby tak:

  1. Sprawdź rzeczywiste Core Web Vitals i TTFB.
  2. Oddziel czas backendu od czasu renderowania w przeglądarce.
  3. Sprawdź page cache i konfigurację serwera.
  4. Znajdź wolne oraz powtarzalne zapytania do bazy.
  5. Sprawdź zewnętrzne API i inne operacje blokujące request.
  6. Sprawdź WP-Cron i ciężką logikę wykonywaną globalnie.
  7. Sprawdź autoload oraz persistent object cache.
  8. Usuń niepotrzebny JavaScript i CSS z podstron, które go nie wykorzystują.
  9. Popraw LCP, fonty i stabilność układu.
  10. Przetestuj prawdziwe interakcje, szczególnie w WooCommerce.
  11. Zmierz ponownie.

Dopiero na końcu zastanawiałbym się, czy 96 punktów w Lighthouse koniecznie trzeba zamienić na 100.

100 punktów w PageSpeed nie jest celem

PageSpeed Insights jest bardzo dobrym narzędziem diagnostycznym. Problem zaczyna się wtedy, gdy wynik staje się celem samym w sobie.

Strona istnieje dla użytkownika, nie dla Lighthouse.

Jeżeli sklep szybko pokazuje produkt, natychmiast reaguje na wybór wariantu, sprawnie dodaje produkt do koszyka i nie przesuwa przycisku w momencie kliknięcia, to są rzeczywiste korzyści z optymalizacji.

Jeżeli udało się przy okazji zdobyć kilka dodatkowych punktów w PageSpeed, tym lepiej.

Nie warto natomiast komplikować projektu tylko po to, żeby zamienić 97 na 100.

Co robimy, kiedy przejmujemy wolną stronę

Przy utrzymaniu i rozwoju WordPressa nie zaczynamy od instalowania kolejnej wtyczki optymalizacyjnej.

Najpierw ustalamy, gdzie rzeczywiście tracony jest czas: na serwerze, w bazie danych, w kodzie PHP, na zewnętrznym API czy już po stronie przeglądarki.

Przy WooCommerce dodatkowo sprawdzamy najważniejsze interakcje zakupowe, ponieważ szybkie otwarcie strony nie oznacza jeszcze szybkiego sklepu.

Następnie przygotowujemy listę zmian w kolejności od tych, które mogą dać największy efekt, do optymalizacji kosmetycznych.

Jeżeli chcesz sprawdzić, dlaczego Twój WordPress albo WooCommerce działa wolno, napisz do nas. Możemy zacząć od analizy i wskazać konkretne miejsca, które warto poprawić.

Masz pytania?

Czy strona musi mieć 100 punktów w PageSpeed Insights?

Nie. Wynik PageSpeed jest przede wszystkim narzędziem diagnostycznym, a nie celem samym w sobie. Core Web Vitals opierają się na danych od rzeczywistych użytkowników, dlatego strona może mieć mniej niż 100 punktów w teście laboratoryjnym i jednocześnie zapewniać bardzo dobre doświadczenie użytkownikom. Ważniejsze jest znalezienie rzeczywistych wąskich gardeł i poprawienie LCP, INP oraz CLS.

Dlaczego wynik PageSpeed zmienia się między kolejnymi testami?

PageSpeed wykonuje test laboratoryjny w warunkach, które mogą różnić się między uruchomieniami. Wpływ mają między innymi czas odpowiedzi serwera, zewnętrzne skrypty, reklamy, testy A/B i aktualne obciążenie infrastruktury. Dlatego nie warto wyciągać wniosków z różnicy kilku punktów między dwoma testami. Lepiej wykonać kilka pomiarów i porównać je z danymi od rzeczywistych użytkowników.

Po jakim czasie PageSpeed i Core Web Vitals pokażą efekt optymalizacji?

Zmiany w teście laboratoryjnym możesz zobaczyć od razu po wdrożeniu. Dane rzeczywistych użytkowników wykorzystują natomiast 28-dniowe okno, dlatego zmieniają się stopniowo. Pierwsze efekty mogą być widoczne wcześniej, ale pełny obraz pojawia się wraz z zastępowaniem starszych danych nowymi wizytami.

Czy wtyczka cache wystarczy, żeby przyspieszyć WordPressa?

Nie zawsze. Cache strony może znacząco skrócić czas generowania odpowiedzi, ale nie naprawi wolnych interakcji JavaScript, ciężkich skryptów zewnętrznych, źle ładowanych obrazów czy problemów z CLS. Nie rozwiąże też każdego problemu w WooCommerce, gdzie koszyk, kasa, konto użytkownika i inne dynamiczne elementy nie mogą być traktowane tak samo jak statyczna podstrona.

PageSpeed pokazuje, że nie ma wystarczających danych dla mojego adresu. Co to znaczy?

Strona ma za mało odwiedzin od użytkowników Chrome spełniających kryteria zbierania danych albo została niedawno opublikowana. W takiej sytuacji PageSpeed pokazuje dane dla całej domeny zamiast dla konkretnego adresu. Zwróć uwagę na etykietę nad wykresem, bo łatwo wziąć ocenę całej witryny za ocenę testowanej podstrony.

Czy szybkość strony wpływa na SEO?

Tak, Core Web Vitals są jednym z sygnałów związanych z doświadczeniem użytkownika wykorzystywanych przez Google. Nie oznacza to jednak, że poprawienie wyniku PageSpeed z 70 do 100 automatycznie podniesie pozycję strony. Trafność i jakość treści nadal mają podstawowe znaczenie. Wydajność warto poprawiać przede wszystkim dla użytkowników, a korzyści SEO traktować jako jeden z efektów dobrej optymalizacji.

Jak sprawdzić, co naprawdę spowalnia WordPressa?
Najpierw ustal, czy czas tracony jest na backendzie, czy w przeglądarce. Przy wysokim TTFB sprawdź między innymi Query Monitor, zapytania SQL, zewnętrzne API, WP-Cron, autoload w wp_options i kod wykonywany przy każdym requeście. Po stronie przeglądarki wykorzystaj DevTools do analizy JavaScriptu, CSS, obrazów, fontów i zewnętrznych skryptów. PageSpeed powinien być jednym z narzędzi diagnostycznych, a nie jedynym.
Czy Redis przyspieszy każdą stronę na WordPressie?
Nie. Redis jako persistent object cache może ograniczyć liczbę powtarzalnych operacji i zapytań do bazy, co jest szczególnie przydatne w bardziej dynamicznych serwisach i WooCommerce. Nie naprawi jednak źle zaprojektowanego WP_Query, ciężkiego meta_query ani kodu pobierającego tysiące niepotrzebnych rekordów. Najpierw warto znaleźć źródło spowolnienia, a dopiero później zdecydować, czy object cache rzeczywiście pomoże.
Co najczęściej spowalnia WordPressa?
Nie ma jednej przyczyny. W praktyce warto sprawdzić czas odpowiedzi serwera, zapytania do bazy, liczbę i sposób działania wtyczek, zewnętrzne API, WP-Cron, autoload w wp_options, skrypty JavaScript, obrazy i fonty. W rozbudowanych stronach częstą przyczyną są też własne fragmenty kodu wykonujące kosztowne operacje przy każdym requeście, mimo że ich wynik można wcześniej obliczyć lub zapisać w cache.

Jacek Sultan

Technical Solutions Architect

CTO i współzałożyciel Dock. Na co dzień zajmuje się projektowaniem i rozwojem aplikacji webowych, architekturą systemów oraz infrastrukturą. Łączy techniczne podejście z perspektywą biznesową, skupiając się na rozwiązaniach, które są proste, niezawodne i mają konkretne uzasadnienie biznesowe. W technologii ceni przede wszystkim praktyczność. Dobre rozwiązanie powinno nie tylko działać, ale też przynosić wartość.

Porozmawiaj z nami