W sklepach internetowych LCP najczęściej opóźnia zdjęcie główne i galeria na karcie produktu, INP pogarszają skrypty integracji, pikseli i widżetów oraz ciężkie filtry, a CLS podnoszą paski, opinie i banery doklejane po załadowaniu strony. Progi są te same co dla każdej strony: LCP do 2,5 s, INP do 200 ms i CLS do 0,1, osiągnięte w co najmniej 75% wizyt (web.dev).
Czym jest INP i dlaczego zastąpił FID, opisałem we wpisie INP zastąpił FID w Core Web Vitals, a ogólne zasady przyspieszania WordPressa w tekście Jak przyspieszyć stronę na WordPressie. Tu skupiam się na tym, co jest typowe dla sklepów.
Zacznij od szablonów, a nie od pojedynczych adresów
Raport Core Web Vitals w Search Console grupuje adresy o podobnym działaniu, a status grupy wyznacza najgorszy wskaźnik (pomoc Search Console). W sklepie grupy pokrywają się zwykle z szablonami: strona główna, kategoria, karta produktu, wyszukiwarka, koszyk. Poprawka w szablonie karty produktu działa na wszystkie produkty naraz.
- Sprawdzam osobno telefon i komputer, bo Google ocenia je osobno.
- Do testów wybieram trudne przypadki: produkt z wieloma zdjęciami i wariantami, kategorię z dużą liczbą produktów i włączonymi filtrami.
- Wynik Lighthouse traktuję jako diagnozę. Ocena w Search Console pochodzi z danych prawdziwych użytkowników z ostatnich 28 dni.
Filtry i strony kategorii
- Filtry, które przeładowują całą stronę albo uruchamiają ciężki kod po każdym kliknięciu, wydłużają reakcję na interakcję. Przy każdej zmianie filtra przeglądarka przebudowuje listę produktów, a im większa lista, tym dłużej to trwa.
- Duża liczba elementów na stronie - kategoria z kilkudziesięcioma kartami, z których każda ma ukryte warianty, szybki podgląd i porównanie, potrafi przekroczyć 1400 elementów, przy których Lighthouse uznaje strukturę strony za zbyt dużą (web.dev). Pomaga mniejsza liczba produktów na stronie, prostsza karta i dociąganie ukrytych elementów dopiero wtedy, gdy są potrzebne.
- Kombinacje filtrów bez pamięci podręcznej - każda kombinacja to nowy adres, więc serwer liczy ją od zera. Wydłuża to czas odpowiedzi serwera, a pośrednio LCP.
- Roboty w filtrach - Google opisuje, że nawigacja fasetowa potrafi wygenerować bardzo dużo adresów, które roboty odwiedzają, obciążając serwer. Zaleca między innymi blokadę parametrów filtrów w robots.txt, jeśli te adresy nie mają być w wynikach, i kod 404 dla kombinacji bez wyników (Google Search Central).
- Miniatury - w rozmiarze pasującym do kafelka, z atrybutami width i height. Leniwe ładowanie zostawiam dla produktów poniżej pierwszego rzędu.
Karta produktu i galeria zdjęć
- Elementem LCP na karcie produktu jest zwykle zdjęcie główne. Nie może mieć leniwego ładowania, bo opóźnia to LCP (web.dev).
- Pierwsze widoczne zdjęcie galerii dostaje atrybut fetchpriority z wartością high, a kolejne zdjęcia niski priorytet, żeby nie konkurowały o łącze (web.dev).
- Pierwsze zdjęcie jest w kodzie HTML od początku, a nie wstawiane przez skrypt slidera po jego uruchomieniu. Miejsce na galerię jest zarezerwowane proporcjami, żeby nic nie przeskakiwało.
- Biblioteki powiększania zdjęć i podglądu pełnoekranowego ładuję dopiero, gdy klient kliknie zdjęcie.
- Przy produktach z dużą liczbą kombinacji dane wszystkich wariantów potrafią mocno powiększyć stronę i spowolnić zmianę wariantu. Sprawdzam, ile danych trafia do przeglądarki przy pierwszym ładowaniu.
- Film z YouTube na karcie produktu zastępuję podglądem, który ładuje odtwarzacz dopiero po kliknięciu.
- Sekcje „podobne produkty” i „ostatnio oglądane” ładuję po głównej części strony.
Skrypty integracji i pikseli
Sklep ładuje zwykle wiele skryptów zewnętrznych: Google Tag Manager i Analytics, piksele reklamowe, widżet opinii, czat, okno zapisu do newslettera, kalkulator rat, mapę punktów odbioru, rekomendacje produktów. Każdy z nich zajmuje przeglądarkę, a razem potrafią wyraźnie pogorszyć INP i LCP.
- Spisuję wszystkie skrypty i strony, na których są potrzebne. Mapa punktów odbioru jest potrzebna w zamówieniu, a kalkulator rat na karcie produktu, a nie na każdej podstronie.
- Skrypty, które nie muszą działać przed wyświetleniem strony, ładuję asynchronicznie albo z opóźnieniem (web.dev).
- Tagi marketingowe warto uruchamiać przez Google Tag Manager dopiero po zgodzie użytkownika. Tak wymagają zasady zgód na pliki cookies, a przy okazji odciąża to pierwsze ładowanie strony.
- Usuwam tagi po zakończonych kampaniach i narzędziach, z których nikt już nie korzysta.
- Testuję stronę także po wyrażeniu zgody. Lighthouse zwykle widzi stan bez zgody, a klienci, którzy ją wyrazili, ładują komplet skryptów i ich wizyty też trafiają do danych w Search Console.
Wtyczki i moduły sklepu
- Moduły dodające style i skrypty na każdej podstronie, choć działają w jednym miejscu: slider na stronie głównej, tabela rozmiarów, porównywarka, lista życzeń, szybki podgląd.
- Bloki wyliczane przy każdym wyświetleniu, na przykład bestsellery albo produkty powiązane, które omijają pamięć podręczną albo generują wiele zapytań do bazy danych.
- Kilka modułów robiących to samo, na przykład dwa systemy opinii albo dwie wtyczki SEO po zmianie dostawcy.
Sprawdzam to na kopii sklepu: mierzę stronę, wyłączam moduł, mierzę ponownie. Zamiast ogólnej zasady „mniej wtyczek” dostajesz listę z konkretnym wpływem każdego modułu i decyzją, co z nim zrobić.
Hosting i pamięć podręczna w sklepie
- Strony z zawartością koszyka, dla zalogowanych klientów i z indywidualnymi cenami zwykle omijają pamięć podręczną stron, więc każde wyświetlenie liczy PHP i baza danych. Tu liczy się wydajność serwera, pamięć podręczna obiektów i szybkie zapytania.
- Czas odpowiedzi serwera (TTFB) nie jest wskaźnikiem Core Web Vitals, ale web.dev zaleca, żeby nie przekraczał 0,8 s, bo poprzedza wszystko, co dzieje się później, w tym LCP (web.dev).
- Importy i synchronizacje z BaseLinkerem, ERP i hurtowniami w ciągu dnia obciążają ten sam serwer, który obsługuje klientów. Ciężkie importy przenoszę poza godziny sprzedaży i zamieniam pełne na przyrostowe.
- Powrót z karty produktu do kategorii może być natychmiastowy dzięki pamięci przeglądarki dla nawigacji wstecz (bfcache). Blokują ją między innymi obsługa zdarzenia unload i nagłówek Cache-Control: no-store. Sprawdzisz to w Chrome DevTools, w zakładce Application (web.dev).
- Przy sprzedaży za granicę zdjęcia i pliki statyczne serwuję z sieci serwerów w różnych krajach.
Obrazy w sklepie: produkty, banery, miniatury
- Zdjęcia produktów wgrywane prosto z aparatu albo od producenta zamieniam na zestaw rozmiarów pod konkretne miejsca: miniaturę na liście, zdjęcie na karcie, powiększenie. Przeglądarka wybiera rozmiar na podstawie atrybutów srcset i sizes.
- Każde zdjęcie ma width i height albo proporcje w CSS, żeby lista produktów nie przeskakiwała podczas ładowania.
- Slider banerów na stronie głównej: pierwszy slajd jest zwykle elementem LCP, więc traktuję go jak zdjęcie główne produktu, a kolejne slajdy ładuję później.
- Po zmianie motywu albo rozmiarów miniatur generuję je na nowo, żeby sklep nie skalował dużych plików w przeglądarce.
- Zespołowi zostawiam prostą zasadę: maksymalny wymiar i format zdjęć wgrywanych do panelu.
Czcionki
- Zestaw ikon ładowany w całości po to, żeby pokazać kilka symboli w nagłówku i stopce, zamieniam na pojedyncze ikony SVG.
- Ograniczam liczbę krojów i grubości do tych, które faktycznie są w projekcie, w formacie WOFF2.
- Zestaw znaków musi obejmować polskie litery. Jeśli czcionka jest przycięta tylko do podstawowego alfabetu łacińskiego, litery takie jak ą czy ł wyświetlają się czcionką zastępczą.
- Sposób wyświetlania czcionki (font-display) dobieram tak, żeby zamiana czcionki zastępczej na docelową nie przesuwała tekstu (web.dev).
Elementy, które przesuwają układ
- Paski z kodem rabatowym albo informacją o darmowej dostawie wstawiane nad treścią po załadowaniu strony. Zalecenie web.dev jest proste: nie dodawać treści nad istniejącą bez interakcji użytkownika (web.dev).
- Widżety opinii, rat i dostępności, które pojawiają się bez zarezerwowanego miejsca.
- Przyklejony pasek „Dodaj do koszyka”, który wsuwa się, przesuwając treść, zamiast nakładać się na nią.
- Baner zgód na pliki cookies wstawiony w układ strony zamiast nad nią.
Kolejność prac
- Search Console: który szablon ma najgorszy wynik na telefonach.
- Odtworzenie problemu na reprezentatywnym adresie w PageSpeed Insights i narzędziach przeglądarki.
- LCP: zdjęcie główne produktu, pierwszy baner, czas odpowiedzi serwera.
- INP: skrypty zewnętrzne, filtry, zmiana wariantu.
- CLS: zarezerwowane miejsce na zdjęcia, widżety i paski.
- Pomiar po wdrożeniu i odczyt w Search Console po pełnych 28 dniach danych.
Najczęstsze pytania
Który szablon sklepu poprawiać najpierw?
Ten, który ma najgorszy wynik w Search Console i najwięcej wejść, zwykle kartę produktu albo kategorię. Poprawka szablonu obejmuje od razu wszystkie adresy z grupy.
Czy wynik 100 w Lighthouse oznacza dobre Core Web Vitals?
Nie. Lighthouse to test laboratoryjny na jednym urządzeniu, bez Twoich klientów, ich telefonów i zgód na skrypty. Ocena Google pochodzi z danych prawdziwych użytkowników.
Czy muszę usuwać piksele reklamowe?
Nie. Wystarczy, że ładują się tylko tam, gdzie są potrzebne, po zgodzie użytkownika i bez blokowania wyświetlenia strony.
Czy zmiana hostingu poprawi Core Web Vitals?
Pomoże, jeśli problemem jest czas odpowiedzi serwera. Nie poprawi INP pogorszonego przez skrypty ani CLS z widżetów bez zarezerwowanego miejsca.
Kiedy zobaczę zmianę w Search Console?
Dane w raporcie obejmują ostatnie 28 dni, więc pełny obraz po wdrożeniu widać po około miesiącu. Pierwsze sygnały zmiany pojawiają się wcześniej.
Pracę nad samymi wskaźnikami prowadzę w ramach optymalizacji Core Web Vitals, a gdy sklep jest wolny w wielu miejscach naraz, szersza optymalizacja szybkości sklepu internetowego porządkuje zdjęcia, moduły, pamięć podręczną i bazę danych.