Stara wersja strony na telefonie: dwa cache w WordPressie

Pod koniec października robiłem większą porcję zmian na stronie klienta z branży myjni samochodowych. WordPress, motyw OceanWP, strony zbudowane w Elementorze, a do tego wtyczka wydajnościowa Seraphinite Accelerator w wersji darmowej. Rozbudowałem siedem podstron z opisami programów mycia, przepisałem dwa wpisy na blogu i zdjąłem emoji ze stron programów.

Przy kontroli po zmianach wyszło, że cztery z siedmiu stron programów nie pokazują nowej sekcji, i to nawet po zalogowaniu do panelu. Jeden z przepisanych wpisów na telefonie dalej miał stary tytuł. W edytorze wszystko było zapisane poprawnie.

Dwie warstwy, które nie wiedzą o sobie nawzajem

Na takiej stronie stara wersja może siedzieć w dwóch miejscach.

Pierwsze to Elementor. Z danych strony generuje własne pliki stylów i dane, które potem serwuje. Jeśli te pliki się nie odświeżą, strona wygląda tak jak przed zmianą, również dla zalogowanego administratora.

Drugie to wtyczka wydajnościowa. Seraphinite trzyma gotową, przetworzoną kopię całej strony i podaje ją odwiedzającym. Zapis w edytorze Elementora tej kopii nie przetwarza od nowa. Do tego zaraz po zapisie wtyczka przez kilkanaście sekund podaje jeszcze poprzednią wersję, więc sprawdzanie od razu po kliknięciu „Zapisz” niczego nie dowodzi.

Każda z tych warstw ma swój przycisk do czyszczenia. Wyczyszczenie jednej nie rusza drugiej.

Procedura po każdej zmianie treści

Od tego wdrożenia po każdej zmianie na tej stronie robię to samo, w tej kolejności:

  1. Elementor > Narzędzia > „Wyczyść pliki i dane”. Elementor generuje style od nowa.
  2. Seraphinite Accelerator > Manager > Operate > „Revalidate cache”, dla wszystkich adresów albo tylko dla tych, które się zmieniły.
  3. Sprawdzenie jako niezalogowany, osobno w widoku komputera i telefonu. Wtyczki cache zwykle podają gotowe kopie tylko niezalogowanym, więc administrator może widzieć nową wersję wtedy, gdy klient widzi starą.

Jedna uwaga do drugiego kroku: nie warto puszczać pełnego przetwarzania kilka razy z rzędu. Przy jednej próbie pod obciążeniem przetwarzanie strony głównej przekroczyło limit 30 sekund i trzeba było je powtórzyć. Lepiej odczekać i sprawdzić wynik po odświeżeniu.

Po tej procedurze wszystkie strony programów i wpis z tytułem pokazały się poprawnie, na komputerze i na telefonie.

Zmiana przez REST API, która nie pojawiła się na stronie

Większość zmian wprowadzałem przez REST API WordPressa, na haśle aplikacji, zamiast przeklikiwać kilkanaście stron w edytorze. Przed zmianami zrobiłem kopię wszystkich ruszanych stron i wpisów razem z danymi Elementora.

Treść stron Elementora siedzi w polu _elementor_data. Zapis tego pola przez API przechodzi bez błędu i w bazie jest nowa wersja. Na stronie dalej widać starą. Nie pomogło ani „Wyczyść pliki i dane”, ani ponowny zapis przez API.

Zadziałało dopiero otwarcie strony w edytorze Elementora i zapisanie jej tam. Przy wielu stronach nie robię tego ręcznie: w przeglądarce, w której jestem zalogowany do panelu, otwieram edytor strony, czekam, aż się załaduje, i wywołuję zapis z konsoli poleceniem Elementora:

$e.run('document/save/update', { force: true });
          

Wpisy zaplanowane na przyszłość zostają przy tym zaplanowane, status się nie zmienia. Dopiero po tym zapisie zaczyna obowiązywać procedura z poprzedniej sekcji.

Przy okazji wyszła jeszcze jedna rzecz, tym razem z motywu: linki wstawione w bloku tekstowym Elementora dziedziczyły biały kolor, więc na jasnym tle były niewidoczne. Starsze wpisy na tej stronie miały kolor linków wpisany bezpośrednio w kod, więc zrobiłem tak samo i sprawdziłem skryptem wszystkie opublikowane strony i wpisy, czy każdy link w treści jest widoczny i ma adres.

Ekran ładowania, który wisiał do pierwszego dotknięcia

W tym samym wdrożeniu poprawiałem szybkość strony na telefonie. Przyczyna wolnego ładowania okazała się splotem dwóch ustawień.

Seraphinite opóźniał cały JavaScript: skrypty startowały po 4,5 sekundy albo przy pierwszej interakcji. Wśród nich był skrypt motywu, który chowa ekran ładowania. W efekcie ciemna nakładka na cały ekran wisiała, dopóki ktoś nie dotknął strony albo nie minął limit czasu. Do tego tło sekcji powitalnej było ładowane leniwie, a na telefon szło zdjęcie o szerokości 1920 pikseli, ważące 449 KB.

Ekranu ładowania nie dało się po prostu wyłączyć, bo zasłaniał moment, w którym wtyczka doładowuje opóźnione style. Bez niego przez kilka sekund widać byłoby rozsypany układ. Zmieniłem więc trzy rzeczy naraz:

  • wyłączyłem ekran ładowania w ustawieniach motywu,
  • wykluczyłem sekcję powitalną z leniwego ładowania w Seraphinite,
  • dodałem osobne tło na telefon: wycinek środka zdjęcia 720 na 1080 pikseli w WebP, 67 KB zamiast 449 KB.

Potem jeszcze raz przetworzyłem cały cache wtyczki.

Strona Czas do pierwszej treści Czas do największego elementu
Strona główna, telefon 0,66 s 0,66 s
Strona lokalizacji, telefon 0,61 s 0,61 s
Strona główna, komputer 0,52 s 0,52 s

Pomiar telefonu robiłem w Chromium ze spowolnieniem łącza i procesora takim jak w PageSpeed (150 ms opóźnienia, 1,6 Mb/s, procesor 4 razy wolniejszy). Waga strony głównej na telefonie spadła z 1,42 MB do 1,04 MB. Dla porównania progi dobrego wyniku to 1,8 sekundy dla pierwszej treści i 2,5 sekundy dla największego elementu.

Lighthouse, który mierzył coś, czego nie było

Najpierw sprawdzałem wynik lokalnym Lighthouse (wersja 13.4) i dostałem 59-68 punktów oraz czas pierwszej treści około 7 sekund. Coś się nie zgadzało, bo przeglądarka pokazywała stronę wyraźnie szybciej.

Okazało się, że Lighthouse liczył dokument HTML jako nieskompresowany: 641 KB. Serwer wysyła go skompresowanego gzipem, przeglądarka dostaje 87 KB. Lighthouse domyślnie symuluje wolny telefon na podstawie jednego szybkiego wczytania, więc zawyżona waga dokumentu przełożyła się wprost na zawyżony czas.

Dlatego liczby w tabeli wyżej pochodzą z pomiaru w prawdziwej przeglądarce ze spowolnieniem, a za ostateczną weryfikację uznaję PageSpeed Insights uruchomiony w przeglądarce i dane od realnych użytkowników w Search Console, które zbierają się przez około 28 dni.

Została jedna otwarta sprawa: darmowa wersja Seraphinite ma limit 5000 odsłon miesięcznie. Co wtyczka robi po jego przekroczeniu, jeszcze sprawdzam.

Co z tego wynika dla Twojej strony

Jeśli masz WordPressa z kreatorem stron i wtyczką cache, zmiana zapisana w edytorze jest dopiero połową roboty. Zanim uznasz, że coś jest na stronie, wyczyść pliki kreatora, przetwórz cache wtyczki i otwórz stronę w oknie prywatnym, także w widoku telefonu. To kilka minut, a oszczędza sytuacji, w której klient pisze, że zmiany nie widać, choć w panelu wszystko wygląda dobrze.

Druga rada dotyczy pomiarów. Wynik z narzędzia to też pomiar, który może się mylić. Gdy liczby nie zgadzają się z tym, co widzisz w przeglądarce, najpierw sprawdź samo narzędzie, a dopiero potem poprawiaj stronę.

Najczęstsze pytania

Najczęściej dlatego, że na stronie działa więcej niż jedna warstwa pamięci podręcznej. Elementor trzyma własne wygenerowane pliki stylów i dane, a wtyczka wydajnościowa trzyma gotową kopię całej strony. Zapis w edytorze odświeża to, co należy do Elementora, ale kopia we wtyczce zostaje, dopóki jej nie przetworzysz od nowa.
Na swoim komputerze to czasem pomaga, ale klient, który wchodzi na stronę pierwszy raz, nie ma u siebie nic do wyczyszczenia. Jeśli on widzi starą wersję, problem leży po stronie serwera. Dlatego po zmianie czyszczę cache na stronie, a sprawdzam w oknie bez logowania, na komputerze i z widokiem telefonu.
Wtyczki cache zwykle podają gotowe kopie tylko odwiedzającym bez logowania, a administrator dostaje stronę generowaną na bieżąco. Zalogowany widzisz więc nowszą wersję i masz poczucie, że wszystko jest w porządku. W tym wdrożeniu część stron była nieaktualna nawet po zalogowaniu, bo zawiodła warstwa samego Elementora.
Można zapisać dane strony w bazie, ale sama zmiana w bazie nie wystarczyła, żeby pojawiła się na stronie. Dopiero otwarcie strony w edytorze Elementora i ponowny zapis wygenerowały nową wersję. Przy kilkunastu stronach robię to skryptem w przeglądarce, jedna strona po drugiej, a zaplanowane wpisy zachowują przy tym swój status.
Zależy, co ten ekran zasłania. Tutaj chował moment, w którym wtyczka wydajnościowa doładowuje opóźnione style, więc samo wyłączenie dałoby na kilka sekund rozsypany układ. Wyłączyłem go dopiero razem z poprawkami w konfiguracji wtyczki i pomiarem przed i po.
Lighthouse domyślnie symuluje wolny telefon na podstawie jednego szybkiego wczytania i błąd w danych wejściowych przenosi się na wynik. Tutaj lokalna wersja liczyła dokument HTML tak, jakby przychodził bez kompresji, i zawyżała czas pierwszej treści do około 7 sekund. Pomiar w prawdziwej przeglądarce ze spowolnieniem łącza i procesora pokazał około 0,65 sekundy.

Sprawdzam, która warstwa trzyma starą wersję, wprowadzam zmiany przez API i weryfikuję je tak, jak zobaczy je klient: bez logowania, na komputerze i na telefonie.

Porozmawiajmy