Core Web Vitals (CWV) stały się w 2024 roku bezpośrednim czynnikiem rankingowym Google, a ich waga w klasyfikacji stron e-commerce dalej rośnie w 2026 roku. W PrestaShop 8 optymalizacja CWV to jednocześnie praca SEO i praca nad jakością doświadczenia: LCP schodzące z 4,2 s do 1,8 s oznacza mechanicznie od 20 do 40 % wyższą konwersję mobilną, zgodnie z badaniami Google i naszymi własnymi pomiarami w prowadzonych sklepach. Mimo to optymalizacja CWV pozostaje źle rozumiana. Większość sprzedawców uruchamia Lighthouse, widzi czerwony wynik, instaluje generyczny moduł cache i stwierdza, że wynik prawie się nie ruszył, bo prawdziwe dźwignie nie tkwią w cache, tylko w konkretnych detalach technicznych.
Ta lista kontrolna omawia optymalizacje CWV, które realnie dają rezultaty w PrestaShop 8 w 2026 roku, z prawdziwym kodem PHP i SQL dopasowanym do architektury PrestaShop, a nie z generycznymi radami przepisanymi z dokumentacji Google.
3 Core Web Vitals roku 2026 i ich progi
Google mierzy trzy metryki oceniające jakość ładowania i interakcji strony.
LCP (Largest Contentful Paint) mierzy czas od rozpoczęcia ładowania do wyrenderowania największego widocznego elementu (typowo głównego zdjęcia na karcie produktu albo tekstu hero na stronie kategorii). Progi: dobry poniżej 2,5 s, do poprawy między 2,5 a 4 s, słaby powyżej 4 s.
INP (Interaction to Next Paint) zastąpiło FID w marcu 2024 roku. Mierzy opóźnienie między interakcją użytkownika (kliknięcie, dotknięcie, wpisanie znaku) a następnym widocznym renderowaniem. Progi: dobry poniżej 200 ms, do poprawy między 200 a 500 ms, słaby powyżej 500 ms.
CLS (Cumulative Layout Shift) mierzy nieprzewidziane przesunięcia wizualne w trakcie ładowania (obraz spychający tekst, baner pojawiający się z opóźnieniem). Progi: dobry poniżej 0,1, do poprawy między 0,1 a 0,25, słaby powyżej 0,25.
Aby strona uzyskała ocenę „Dobra” w Search Console, wszystkie trzy metryki muszą mieścić się w zieleni na 75. percentylu rzeczywistych ładowań (25 % najwolniejszych wizyt może wypadać gorzej, ale 75 % najszybszych musi być dobre). To właśnie utrudnia optymalizację: Twój sklep może być szybki dla odwiedzającego na światłowodzie i desktopie, a katastrofalny dla użytkownika na słabym 4G i tanim Androidzie. Google liczy wynik na prawdziwych użytkownikach (dane terenowe z Chrome User Experience Report).
Pomiar CWV w Twoim sklepie: dane laboratoryjne kontra terenowe
Istnieją dwa rodzaje pomiarów, które trzeba rozróżniać.
Dane laboratoryjne (pomiar syntetyczny). PageSpeed Insights, Lighthouse, WebPageTest. Strona jest ładowana przez robota w ustandaryzowanym środowisku (symulowane 3G, telefon ze średniej półki). Liczby są powtarzalne, ale nie odzwierciedlają doświadczenia Twoich prawdziwych odwiedzających. Przydatne do diagnostyki i pracy deweloperskiej.
Dane terenowe (pomiary rzeczywiste). Chrome User Experience Report (CrUX), dostępny w Search Console w sekcji Ulepszenia, podsekcja Core Web Vitals. To liczby, których Google używa do rankingu. Zagregowany pomiar rzeczywistych ładowań Twoich odwiedzających z ostatnich 28 dni. To metryka, która liczy się dla SEO.
Rozbieżność między danymi laboratoryjnymi a terenowymi bywa ogromna: witryna z wynikiem Lighthouse 95 może mieć dane terenowe na czerwono, jeśli większość odwiedzających korzysta z urządzeń wolniejszych niż standardowy profil Lighthouse. Odwrotnie, witryna z wynikiem 60 może mieć poprawne dane terenowe, jeśli jej odbiorcy siedzą głównie na desktopie.
Narzędzie do wdrożenia już teraz. Skonfiguruj Real User Monitoring (RUM) w swoim sklepie. Kilka darmowych opcji: biblioteka web-vitals od Google, którą integruje się kilkoma liniami JS i która wysyła pomiary do GA4, albo narzędzia takie jak Cloudflare Web Analytics, SpeedCurve czy Calibre. Pomiary RUM są najbliższe temu, co widzi Google, i pozwalają segmentować według typu urządzenia, kraju i przeglądarki, co ujawnia, gdzie leżą Twoje prawdziwe problemy.
LCP: optymalizacje, które naprawdę działają
LCP jest zwykle metryką o największym wpływie biznesowym w PrestaShop, bo dotyczy bezpośrednio odczucia szybkości przy ładowaniu karty produktu. Oto dźwignie w kolejności typowego wpływu.
1. Precyzyjnie zidentyfikuj element LCP
Przede wszystkim ustal, który element wyzwala LCP na Twoich kluczowych stronach. Lighthouse wskazuje go w raporcie, ale najprecyzyjniejszym narzędziem jest rozszerzenie Chrome Web Vitals Extension, które podświetla element LCP w czasie rzeczywistym na dowolnej stronie. Na karcie produktu PrestaShop elementem LCP jest niemal zawsze główne zdjęcie produktu. Na kategorii zwykle pierwsze widoczne zdjęcie z siatki produktów. Na stronie głównej hero albo slider.
Po zidentyfikowaniu to właśnie ten element trzeba priorytetyzować w optymalizacji: wstępne wczytywanie, konwersja do nowoczesnego formatu, właściwe wymiary, wyłączony lazy loading.
2. Wstępne wczytywanie obrazu LCP
Na kartach produktów dodanie <link rel="preload"> w sekcji head dla głównego zdjęcia produktu daje od 200 do 500 ms zysku na LCP, bo przeglądarka zaczyna pobierać obraz, zanim jeszcze sparsuje zawierający go HTML.
Wdrożenie w szablonie karty produktu (themes/twoj-motyw/templates/catalog/product.tpl w Smartym albo w odpowiedniku Twig dla nowoczesnych motywów):
{if isset($product.cover.bySize.large_default.url)}
<link rel="preload" as="image"
href="{$product.cover.bySize.large_default.url}"
imagesrcset="..." imagesizes="..." fetchpriority="high">
{/if}
Atrybut fetchpriority="high" jest ważny, bo mówi przeglądarce, że ten zasób jest krytyczny i musi wyprzedzić inne w kolejce pobierania.
3. Konwersja do WebP i AVIF z poprawnymi wymiarami
Serwowanie zdjęć produktowych w WebP zmniejsza ich wagę o 25 do 35 % wobec JPEG przy porównywalnej jakości wizualnej. AVIF oszczędza kolejne 20 %, ale jego dekodowanie jest nieco kosztowniejsze po stronie przeglądarki. Kompromis roku 2026 to WebP w większości przypadków i AVIF dla krytycznych obrazów hero.
W PrestaShop 8 kilka modułów wykonuje konwersję automatycznie (natywny PrestaShop ma podstawową opcję WebP, moduły zewnętrzne radzą sobie lepiej dzięki AVIF i kompresji adaptacyjnej). Sprawdź też, czy serwowane wymiary odpowiadają rzeczywistemu wyświetlaniu: podawanie obrazu 2000 na 2000 pikseli wyświetlanego w rozmiarze 400 na 400 marnuje transfer i podnosi LCP. Używaj srcset, aby zaproponować kilka rozmiarów zależnie od viewportu.
4. TTFB i zapytania SQL po stronie serwera
LCP jest od dołu ograniczone przez TTFB (Time To First Byte): dopóki serwer nie zacznie wysyłać HTML, przeglądarka nie ma czego renderować. W PrestaShop TTFB potrafią zabijać niezoptymalizowane zapytania SQL w ciężkich hookach.
Audyt do wykonania: włącz profiler PrestaShop (Konfiguracja, Wydajność, tryb debug plus profiler) i sprawdź zakładkę Database. Jeśli widzisz zapytanie wykonujące się 50 razy przy jednym ładowaniu karty produktu z łącznym czasem 200 ms, to prawdopodobnie zapytanie typu N plus 1 w źle napisanym module. Taki moduł trzeba załatać albo wyłączyć.
Najczęstsi winowajcy w audytowanych przez nas sklepach: moduły opinii odpytujące o średnią ocenę dla każdego wyświetlanego produktu bez cache, moduły produktów powiązanych wykonujące jedno zapytanie na każdy rekomendowany produkt, moduły magazynowe liczące dostępność przy każdym wyświetleniu produktu. Nasza kategoria Wydajność i Core Web Vitals omawia kilka takich wzorców.
INP: nowoczesny zabójca wydajności (i najgorzej rozumiany)
INP zastąpiło FID w marcu 2024 roku i jest dziś najtrudniejszą do optymalizacji metryką w PrestaShop. Powód: FID mierzyło tylko pierwszą interakcję, a INP mierzy wszystkie i zachowuje najgorszy 98. percentyl. Jedna wolna interakcja na 50 (na przykład kliknięcie w filtr kategorii zawieszające stronę na 500 ms) waży więc więcej niż 49 szybkich.
1. Zidentyfikuj wolne interakcje
Rozszerzenie Chrome Web Vitals Extension pokazuje INP w czasie rzeczywistym podczas nawigacji. Klikaj po całym sklepie (filtry, dodanie do koszyka, popupy, akordeony FAQ, karuzela produktu) i sprawdzaj, które interakcje przekraczają 200 ms. W PrestaShop typowi winowajcy to:
- filtry kategorii (wyszukiwanie fasetowe), które przeładowują całą siatkę przez AJAX;
- dodania do koszyka wyzwalające ciężkie hooki;
- otwarcia okna modalnego produktu (Quick View);
- zmiany wariantu produktu (kolor, rozmiar).
2. Długie zadania i oddawanie kontroli głównemu wątkowi
Wolna interakcja jest niemal zawsze spowodowana „długim zadaniem” JavaScript (funkcją blokującą główny wątek dłużej niż 50 ms). Przeglądarka nie może odpowiedzieć na kolejne kliknięcia, dopóki długie zadanie się nie skończy.
Nowoczesne rozwiązanie: podziel długie zadania przy pomocy scheduler.yield() (natywne API w nowszych przeglądarkach Chromium) albo wzorca setTimeout(fn, 0), aby oddawać kontrolę przeglądarce między fragmentami obliczeń. Przykład: jeśli masz pętlę przetwarzającą 1000 produktów po stronie frontu, podziel ją na porcje po 50 z oddaniem kontroli między każdą.
async function processProducts(products) {
for (let i = 0; i < products.length; i += 50) {
const chunk = products.slice(i, i + 50);
chunk.forEach(processProduct);
if ('scheduler' in window && 'yield' in scheduler) {
await scheduler.yield();
} else {
await new Promise(r => setTimeout(r, 0));
}
}
}
3. Debounce i throttle na polach formularzy
Przy filtrach wyszukiwania, listach wyboru wariantu i polach ilości nie wyzwalaj AJAX-a przy każdym naciśnięciu klawisza. Zastosuj debounce od 200 do 300 ms przed wysłaniem żądania. Bez tego detalu odwiedzający piszący szybko generuje 10 żądań AJAX, które wszystkie zapychają główny wątek.
4. Dzielenie kodu JS i ładowanie odroczone
Wiele modułów PrestaShop ładuje swój JS na wszystkich stronach, mimo że są używane tylko na niektórych (moduł Quick View ładujący się na stronie głównej, moduł FAQ ładujący się na stronach kategorii). Zaudytuj swoje kontrolery i używaj $this->context->controller->registerJavascript() z właściwym kontrolerem w parametrze, aby ograniczyć ładowanie do stron, gdzie JS jest potrzebny.
Przy naprawdę ciężkich funkcjach (karuzela Swiper, edytor WYSIWYG) ładuj JS leniwie przez dynamiczny import() w momencie pierwszej interakcji, a nie przy ładowaniu strony.
CLS: stabilność wizualna
CLS jest zwykle najłatwiejszą do naprawienia metryką w PrestaShop, bo przyczyn jest niewiele i są dobrze znane.
1. Rezerwacja miejsca na obrazy. Każdy obraz w HTML musi mieć jawne atrybuty width i height (albo aspect-ratio w CSS). Bez tego obraz zmienia układ strony w momencie wczytania. W PrestaShop zdjęcia produktów generowane przez hooki displayProduct... muszą mieć swoje wymiary. Sprawdź kod motywu: każdy <img src="..." /> bez width i height jest podejrzany.
2. Fonty webowe oraz FOIT i FOUT. Jeśli używasz Google Fonts albo fontów własnych, przeglądarka może wyświetlić niewidoczny tekst (FOIT), a potem gwałtownie przełączyć (FOUT), gdy font dotrze, co przesuwa całą treść. Rozwiązanie: font-display: optional w CSS dla fontów drugorzędnych oraz font-display: swap z fontem zastępczym zgodnym metrycznie (użyj właściwości CSS size-adjust, aby dopasować font zastępczy do własnego i wyeliminować przesunięcie).
3. Banery i popupy z opóźnieniem. Paski cookies, popupy newslettera i górne banery pojawiające się od 1 do 3 sekund po załadowaniu to częste źródła CLS. Rozwiązanie: zarezerwuj miejsce w CSS od początku (przez min-height), jeśli wiesz, że baner się pojawi, albo pokaż go jako nakładkę (position fixed lub absolute), która nie przesuwa istniejącej treści.
4. Zewnętrzne ramki iframe i osadzenia. Ramki YouTube, Vimeo czy Calendly ładujące się z opóźnieniem przesuwają treść. Systematycznie rezerwuj im miejsce kontenerem z aspect-ratio: 16/9 albo odpowiednikiem.
Optymalizacje SQL i bazy danych specyficzne dla PrestaShop
W PrestaShop istotna część TTFB (a więc i LCP) pochodzi z zapytań SQL. Oto wzorce, które warto znać.
Profilowanie z EXPLAIN
Gdy profiler PrestaShop wskaże wolne zapytanie (powyżej 50 ms), przepuść je w MySQL przez EXPLAIN, aby zrozumieć, co się dzieje. Jeśli widzisz type: ALL z dużą liczbą skanowanych wierszy, prawdopodobnie brakuje indeksu. Jeśli widzisz Using filesort albo Using temporary, zapytanie wykonuje zbędną pracę i wymaga przepisania.
Typowo brakujące indeksy w PrestaShop
W sklepach z dużym katalogiem (ponad 5000 produktów) i wieloma modułami zewnętrznymi często brakuje pewnych indeksów. Wzorce, które widzimy w audytach:
- brak indeksu na
id_product, id_shopwe własnych tabelach modułów; - brak indeksu na kolumnach używanych do filtrów kategorii (wyszukiwanie fasetowe);
- brak indeksu na
id_order, date_adddla zapytań statystycznych o zamówienia.
Dodaj brakujące indeksy bezpośrednio w SQL przez PhpMyAdmin albo przez migrację modułu. Zmierz przed i po: jeden dobrze postawiony indeks potrafi skrócić czas zapytania pięćdziesięciokrotnie.
Zapytania N plus 1 w hookach
Najbardziej niszczący wzorzec wydajnościowy w PrestaShop: hook wykonujący się dla każdego wyświetlanego produktu i robiący jedno zapytanie SQL na produkt. Na kategorii pokazującej 24 produkty daje to 24 dodatkowe zapytania na każde ładowanie.
Wykrywanie: profiler PrestaShop, zakładka Database. Jeśli widzisz to samo zapytanie powtórzone N razy z różnymi parametrami, masz N plus 1.
Rozwiązanie: przerobić moduł tak, aby grupował zapytania. Zamiast wykonywać jedno zapytanie na produkt w hooku displayProductMiniature, moduł powinien zebrać wszystkie identyfikatory produktów przez actionProductListBefore i wykonać jedno zapytanie WHERE id_product IN (1, 2, 3, ...), które zwróci wszystkie wyniki naraz.
Cache PrestaShop: Smarty plus cache modułu
W PrestaShop 8 uzupełniają się dwa poziomy cache. Cache Smarty (kompilujący szablony do PHP) jest używany na produkcji: sprawdź SMARTY_CONSOLE_FORCE_COMPILE = 0 i SMARTY_CACHE = 1 w pliku config/defines.inc.php. Cache modułu (własny cache wewnątrz modułów) jest potężniejszy: dobrze napisany moduł cache’uje swoje ciężkie obliczenia i powtarza je dopiero przy zmianie danych. Jeśli moduł przelicza na każdej stronie to samo, to błąd do naprawienia.
W sklepach o dużym ruchu dołóż też cache HTTP (Varnish albo cache LiteSpeed po stronie hostingu), który serwuje wstępnie wyrenderowane strony produktów, nie dotykając w ogóle PrestaShop. To dzieli TTFB przez 10 przy powtarzalnych żądaniach i uwalnia serwer dla żądań naprawdę dynamicznych.
Pułapka modułów zewnętrznych
W audytowanych przez nas sklepach od 60 do 80 % problemów z CWV pochodzi ze źle napisanych modułów zewnętrznych. Wzorzec jest zawsze ten sam: moduł zainstalowany dla przydatnej funkcji (czat na żywo, popup newslettera, plakietka lojalnościowa, dowód społeczny) ładuje ciężki JS na wszystkich stronach, obciąża LCP i INP, a nikt nie łączy jednego z drugim.
Audyt do regularnego wykonywania:
- Wyłącz wszystkie moduły zewnętrzne i uruchom Lighthouse, uzyskując punkt odniesienia „czysty PrestaShop”.
- Włączaj moduły pojedynczo, uruchamiając Lighthouse za każdym razem.
- Zidentyfikuj moduły obniżające wynik o więcej niż 5 punktów, bo to Twoi winowajcy.
- Dla każdego winowajcy: albo znajdź ustawienie, które go odchudzi, albo zastąp go lepiej napisaną alternatywą, albo uznaj, że funkcja nie jest warta tego pogorszenia.
Kryterium wyboru nowego modułu w 2026 roku: przed instalacją sprawdź, czy moduł ładuje swoje zasoby tylko na stronach, na których jest używany (a nie wszędzie), czy grupuje zapytania SQL (bez N plus 1), czy oferuje konfigurowalny cache i czy ma świeży changelog (moduł nieutrzymywany od 18 miesięcy na PrestaShop 8 jest podejrzany).
Kilka modułów z naszego katalogu powstało z myślą właśnie o tych ograniczeniach, na przykład moduł DataFirefly SideCart, który ładuje swój JS wyłącznie na stronach, gdzie się wyświetla, albo moduł DataFirefly Cross-Sell, którego analityka wychodzi przez AJAX poza ścieżką krytyczną, żeby nie obciążać LCP. Temat rozwijamy w artykule o cross-sellingu podnoszącym średni koszyk.
Podsumowanie: praca ciągła, a nie jednorazowy projekt
Optymalizacja Core Web Vitals w PrestaShop 8 rzadko jest pracą na kilka dni, którą wykonuje się raz i zapomina. To praca ciągła: każdy nowy moduł może zepsuć wynik, każda aktualizacja PrestaShop może wprowadzić regresje, a każda zmiana po stronie Google (jak wejście INP w marcu 2024 roku) może przetasować priorytety.
Dobrym odruchem jest wdrożenie stałego monitoringu (Search Console plus RUM przez web-vitals.js plus GA4) i rutynowe sprawdzanie metryk, a nie dopiero wtedy, gdy problem staje się widoczny. Pogorszenie wykryte w pierwszym tygodniu naprawia się w kilka godzin, a to samo pogorszenie wykryte w ósmym tygodniu, po dołożeniu w międzyczasie trzech kolejnych modułów, staje się kilkudniowym audytem całości.
Aby pójść dalej, przejrzyj kategorie Wydajność i Core Web Vitals oraz Tutoriale PrestaShop po pokrewne tematy techniczne. A jeśli wykryjesz w swoim obecnym stacku moduły, które psują CWV, nie dając odpowiedniej wartości, kilka modułów z naszego katalogu zostało zaprojektowanych jako wydajnościowe z założenia: SideCart, Cross-Sell i cała gama DataFirefly dzielą to samo zobowiązanie: żadnego JS na stronach, gdzie moduł się nie wyświetla, żadnych N plus 1, żadnych zbędnych zależności zewnętrznych.
Przeczytaj także: kompletny przewodnik po Core Web Vitals.
Aby przejść do działania: nasz wybór modułów przyspieszających sklep PrestaShop.