Optymalizacja wydajności PrestaShop: Przyspiesz swój sklep
Kompletny przewodnik optymalizacji wydajności — OPcache, MySQL, konfiguracja CCC, optymalizacja obrazów, strategie cache i Core Web Vitals.
Dlaczego szybkość sklepu to nie opcja
Każde dodatkowe 100 milisekund czasu ładowania kosztuje Cię konwersje. Amazon odkrył, że opóźnienie 100ms zmniejszało przychody o 1%. Google potwierdził, że strony ładujące się dłużej niż 3 sekundy tracą 53% mobilnych odwiedzających, zanim ci zdążą zobaczyć Twoje produkty.
W przypadku sklepu PrestaShop szybkość wpływa bezpośrednio na trzy rzeczy:
- Współczynniki konwersji: Sklep, który ładuje się w 2 sekundy, konwertuje mniej więcej dwukrotnie lepiej niż ten, który ładuje się w 5 sekund. Twoi klienci nie będą czekać — kupią od kogoś szybszego.
- Pozycje w SEO: Google używa szybkości strony jako czynnika rankingowego. Od 2021 roku Core Web Vitals są częścią algorytmu. Wolny sklep zajmuje niższe pozycje, otrzymuje mniej ruchu organicznego i płaci więcej za widoczność.
- Doświadczenie mobilne: Ponad 70% ruchu w e-commerce to ruch mobilny. Wolniejsze procesory, mniej pamięci, gorsze połączenia. Jeśli Twój sklep jest wolny na desktopie, na telefonie jest nie do zniesienia.
Optymalizacja szybkości to nie jednorazowe zadanie — to ciągła dyscyplina. Każdy instalowany moduł, każda zmiana w szablonie, każde zdjęcie produktu wpływa na wydajność. Traktuj szybkość jako funkcję, którą utrzymujesz, a nie projekt, który kończysz.
Mierz zanim zaczniesz optymalizować
Najgorszą rzeczą, jaką możesz zrobić, jest rozpoczęcie „optymalizacji” bez wiedzy, gdzie są rzeczywiste problemy. Zawsze najpierw mierz.
Właściwe narzędzia
- Google PageSpeed Insights: Darmowe, korzysta z rzeczywistych danych użytkowników Chrome (CrUX). Przetestuj stronę główną, stronę kategorii i stronę produktu — to Twoje najczęstsze punkty wejścia.
- GTmetrix: Pokazuje wykres kaskadowy (waterfall), dokładnie co się ładuje, w jakiej kolejności i ile czasu zajmuje każde żądanie. Bezcenne do znajdowania wąskich gardeł.
- WebPageTest: Najbardziej szczegółowe dostępne narzędzie. Testuj z różnych lokalizacji i prędkości połączenia z widokami taśmy filmowej.
Core Web Vitals — objaśnienie
To trzy metryki, których Google używa do oceny doświadczenia użytkownika:
- LCP (Largest Contentful Paint): Czas, aż największy widoczny element zakończy ładowanie. Cel: poniżej 2,5 sekundy. Większość sklepów PrestaShop ma z tym problem — winne są niezoptymalizowane obrazy i skrypty blokujące renderowanie.
- INP (Interaction to Next Paint): Jak długo strona reaguje na kliknięcia i dotknięcia. Zastąpił FID w marcu 2024. Cel: poniżej 200ms. Ciężki JavaScript i źle napisane skrypty modułów powodują wysoki INP.
- CLS (Cumulative Layout Shift): Jak bardzo układ strony przeskakuje podczas ładowania. Cel: poniżej 0,1. Obrazy bez wymiarów, późno ładujące się banery i podmiana czcionek powodują CLS.
Realistyczne cele
Bogaty funkcjonalnie sklep PrestaShop nigdy nie osiągnie 100 punktów w PageSpeed. Celuj w: mobile 50-70, desktop 80-95, LCP poniżej 3s na mobile / 2s na desktop, całkowita waga strony poniżej 2MB, mniej niż 80 zapytań HTTP.
Nie goń za idealnym wynikiem PageSpeed. Wynik 65 z 3% konwersją jest lepszy niż wynik 98 na ogołoconej stronie, z której nikt nie kupuje. Optymalizuj pod rzeczywiste doświadczenie użytkownika, nie pod liczbę.
Optymalizacja serwera
Żadne sztuczki frontendowe nie naprawiaą wolnego serwera. Jeśli Twój serwer potrzebuje 2 sekund na wygenerowanie HTML, zanim przeglądarka w ogóle zacznie ładować zasoby, już przegrałeś.
Konfiguracja PHP OPcache
OPcache przechowuje prekompilowany bajtkod PHP w pamięci, dzięki czemu PHP nie musi ponownie parsować plików przy każdym żądaniu. Dla PrestaShop (setki plików PHP na stronę) to obowiązkowe.
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.save_comments=1
Domyślne wartości są zbyt niskie dla PrestaShop. max_accelerated_files musi wynosić co najmniej 20000 (domyślnie 4000, ale typowa instalacja PS ma 10 000-15 000 plików PHP). Ustaw memory_consumption na 128-256MB — jeśli pamięć OPcache się zapełni, wpisy są usuwane i tracisz korzyści.
Na hostingach cPanel z validate_timestamps=0 OPcache NIGDY nie odczytuje ponownie plików z dysku. Musisz go zresetować przez żądanie webowe po każdym wdrożeniu — reset z CLI czyści tylko cache CLI, a nie cache webowe.
Tuning MySQL / MariaDB
Typowa strona produktu w PrestaShop wykonuje 50-200 zapytań SQL. Najważniejsze ustawienie bazy danych to:
[mysqld]
# Set to 50-70% of available RAM on dedicated DB server
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
# MySQL 5.7 / MariaDB only (removed in MySQL 8.0)
query_cache_type = 1
query_cache_size = 64M
# Find problem queries
slow_query_log = 1
long_query_time = 1
# Connection settings
max_connections = 150
tmp_table_size = 64M
max_heap_table_size = 64M
innodb_buffer_pool_size określa, ile danych bazy jest trzymanych w pamięci RAM. Jeśli Twoja baza ma 500MB, a buffer pool 1GB, większość zapytań jest obsługiwana z pamięci. Włącz slow query log i przeglądaj go co tydzień — zapytania trwające ponad 1 sekundę to problemy czekające na wystąpienie przy szczytowym ruchu.
Hosting: współdzielony vs VPS vs dedykowany
- Hosting współdzielony ($5-15/miesiąc): Dzielisz CPU i RAM z setkami stron. Akceptowalny tylko dla bardzo małych sklepów poniżej 500 produktów.
- VPS ($20-60/miesiąc): Dedykowane zasoby. Optymalny wybór dla większości sklepów. Potrzebujesz minimum 4GB RAM, 2 rdzenie CPU, dysk SSD.
- Dedykowany ($80-300/miesiąc): Dla sklepów z dużym ruchem (1000+ zamówień dziennie) lub katalogów powyżej 100 000 produktów.
Jeśli jesteś na hostingu współdzielonym i Twój sklep jest wolny, przejście na VPS da Ci większy wzrost szybkości niż wszystkie inne optymalizacje razem wzięte.
PHP-FPM i Redis
Używaj PHP-FPM zamiast mod_php — uruchamia PHP jako osobną usługę, zmniejszając zużycie pamięci i poprawiając zarządzanie procesami. Używaj Redis do przechowywania sesji i cache zamiast systemu plików. Konfiguracja w app/config/parameters.php:
'ps_cache_enable' => true,
'ps_caching' => 'CacheRedis',
Wbudowane optymalizacje PrestaShop
CCC (Combine, Compress, Cache)
Dostępne w Zaawansowane → Wydajność, CCC łączy pliki CSS/JS w pojedyncze pliki i minifikuje je. Zawsze włączaj na produkcji. Uważaj na pułapki:
- Pliki z atrybutem
deferlubasyncpozostają oddzielne (celowo) - Pliki zewnętrzne (Google Fonts, Stripe.js) nigdy nie są łączone
- Źle napisane moduły mogą się zepsuć, gdy CCC zmieni kolejność zasobów — jeśli włączenie CCC psuje Twój checkout, wyłącz je i zidentyfikuj problematyczny moduł
- Zawsze wyczyść cache i dokładnie przetestuj po włączeniu
Ustawienia szablonów Smarty
Ustaw kompilację szablonów na „Rekompiluj szablony, jeśli pliki zostały zaktualizowane” na produkcji. Nigdy nie używaj „Wymuś kompilację” — rekompiluje każdy szablon przy każdym załadowaniu strony.
Tryb debugowania — sprawdź to najpierw
Tryb debugowania wyłącza całe cache, wymusza rekompilację szablonów i loguje wszystko. Sprawdź, czy jest wyłączony:
// In app/config/defines.inc.php — MUST be false on production
define('_PS_MODE_DEV_', false);
Widzieliśmy sklepy działające w trybie debugowania przez miesiące. Ich problem z „wolnym sklepem” zniknął, gdy ta jedna opcja została poprawiona.
Wyłącz niepotrzebne moduły
Każdy włączony moduł wpina się w system zdarzeń PrestaShop. Świeża instalacja zawiera ponad 80 modułów. Każdy z nich ładuje klasy PHP, może rejestrować CSS/JS na każdej stronie, wykonuje callbacki hooków i może uruchamiać zapytania do bazy — nawet gdy zwraca pustą treść.
Przejdź do Moduły → Menedżer modułów i odinstaluj wszystko, czego aktywnie nie używasz. Jeśli masz trzy moduły analityczne robiace to samo, zostaw jeden.
Optymalizacja obrazów
Obrazy stanowią zwykle 60-80% całkowitej wagi strony. To tutaj większość sklepów ma największy potencjał poprawy.
WebP i właściwe wymiary
Obrazy WebP są o 25-35% mniejsze niż JPEG bez widocznej utraty jakości. PrestaShop 8.x obsługuje WebP natywnie. Dla starszych wersji użyj konwersji po stronie serwera lub modułu.
Najczęstsze marnotrawstwo: serwowanie obrazów 2000x2000px w miniaturkach 300px. Skonfiguruj typy obrazów w Wygląd → Ustawienia obrazów, aby odpowiadały rzeczywistym rozmiarom wyświetlania w Twoim szablonie. Nie przesyłaj obrazów źródłowych 4000px „na wszelki wypadek” — 1200px wystarczy do zoomu na stronie produktu na ekranach retina.
Lazy loading
Odraczaj ładowanie obrazów poniżej zagięcia strony, aż użytkownik do nich przewinie:
<img src="product.jpg" loading="lazy" width="300" height="300" alt="Product Name">
NIE stosuj lazy loading do obrazów powyżej zagięcia (logo, baner główny, pierwszy rząd produktów) — wpływają one na LCP i muszą się załadować natychmiast.
Regeneracja obrazów
Po zmianie wymiarów obrazów zregeneruj istniejące obrazy przez Wygląd → Ustawienia obrazów lub CLI:
php bin/console prestashop:image:regenerate --type=products
Optymalizacja frontendu
Minimalizuj zapytania HTTP
Sprawdź wykres kaskadowy w GTmetrix. Ponad 100 zapytań oznacza problem. Typowi winowajcy: moduły ładujące własne pliki CSS/JS, Google Fonts z wieloma gramaturami, widżety mediów społecznościowych i wiele narzędzi analitycznych.
Critical CSS
Przeglądarki wstrzymują renderowanie, dopóki cały CSS w <head> nie zostanie pobrany. Critical CSS wyodrębnia tylko style potrzebne dla początkowego widoku i wstawia je inline. Pełny arkusz stylów ładuje się asynchronicznie. Może to skrócić postrzegany czas ładowania o 1-3 sekundy na mobile, ale wymaga regeneracji przy każdej zmianie CSS szablonu.
JavaScript: defer i async
Używaj defer dla większości skryptów modułów (pobiera równolegle, wykonuje po sparsowaniu HTML). Używaj async tylko dla niezależnych skryptów, takich jak analityka. W PrestaShop 1.7+:
$this->context->controller->registerJavascript(
'module-my-script',
'modules/mymodule/views/js/front.js',
['position' => 'bottom', 'priority' => 200, 'attribute' => 'defer']
);
Optymalizacja czcionek
Niestandardowe czcionki po cichu dodają 200-400KB pobieranych danych. Najlepsze praktyki:
- Hostuj czcionki samodzielnie zamiast używać Google Fonts (eliminuje dodatkowe wyszukiwanie DNS)
- Ogranicz podzbiór tylko do potrzebnych znaków (podzbiory tylko z łacińskimi znakami są o 60-80% mniejsze)
- Użyj
font-display: swap, aby tekst był widoczny natychmiast w czcionce zastępczej - Ogranicz do 2 grubosci — regular (400) i bold (700) wystarczą w większości przypadków
- Używaj formatu WOFF2 — najlepsza kompresja, uniwersalna obsługa przeglądarek
@font-face {
font-family: 'YourFont';
src: url('/themes/your-theme/assets/fonts/yourfont.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
Podstawy CDN
CDN serwuje pliki statyczne z serwerów bliskich Twoim odwiedzającym. Cloudflare to najpopularniejsza darmowa opcja. Skonfiguruj domenę CDN w Zaawansowane → Wydajność → Serwery mediów dla obrazów, CSS i JS.
Optymalizacja bazy danych
Bazy danych PrestaShop rosną po cichu. Tabele, które były w porządku na starcie, stają się problemem po dwóch latach nagromadzonych danych.
Wyczyść stare koszyki
ps_cart i ps_cart_product rosną z każdym odwiedzającym — włącznie z botami i porzuconymi sesjami. Po roku tabele te mogą mieć miliony wierszy.
-- Delete cart products for old abandoned carts (not linked to orders)
DELETE cp FROM ps_cart_product cp
INNER JOIN ps_cart c ON cp.id_cart = c.id_cart
LEFT JOIN ps_orders o ON c.id_cart = o.id_cart
WHERE o.id_order IS NULL
AND c.date_add < DATE_SUB(NOW(), INTERVAL 3 MONTH);
-- Delete the empty carts
DELETE c FROM ps_cart c
LEFT JOIN ps_orders o ON c.id_cart = o.id_cart
LEFT JOIN ps_cart_product cp ON c.id_cart = cp.id_cart
WHERE o.id_order IS NULL AND cp.id_cart IS NULL
AND c.date_add < DATE_SUB(NOW(), INTERVAL 3 MONTH);
Zawsze zrób kopię zapasową bazy danych przed uruchomieniem zapytań DELETE. Zawsze testuj najpierw na środowisku testowym. Wzór LEFT JOIN + IS NULL zapewnia, że koszyki powiązane z zamówieniami nigdy nie zostaną usunięte.
Wyczyść logi i połączenia
-- Application logs
DELETE FROM ps_log WHERE date_add < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- Visitor tracking
DELETE FROM ps_connections_page WHERE id_connections IN (
SELECT id_connections FROM ps_connections
WHERE date_add < DATE_SUB(NOW(), INTERVAL 3 MONTH)
);
DELETE FROM ps_connections WHERE date_add < DATE_SUB(NOW(), INTERVAL 3 MONTH);
-- Orphaned guest records
DELETE g FROM ps_guest g
LEFT JOIN ps_connections c ON g.id_guest = c.id_guest
WHERE c.id_guest IS NULL;
-- Search stats, 404 logs, email logs
DELETE FROM ps_statssearch WHERE date_add < DATE_SUB(NOW(), INTERVAL 6 MONTH);
DELETE FROM ps_pagenotfound WHERE date_add < DATE_SUB(NOW(), INTERVAL 30 DAY);
DELETE FROM ps_mail WHERE date_add < DATE_SUB(NOW(), INTERVAL 3 MONTH);
Wyczyść indeks wyszukiwania
Jeśli używasz zewnętrznego rozwiązania wyszukiwania (Elasticsearch, Algolia), te tabele są zbędnym balastem:
TRUNCATE TABLE ps_search_index;
TRUNCATE TABLE ps_search_word;
Optymalizuj tabele i indeksy
Po dużych usunięciach odzyskaj przestrzeń dyskową:
OPTIMIZE TABLE ps_cart, ps_cart_product, ps_connections,
ps_connections_page, ps_guest, ps_log;
Dodaj brakujące indeksy dla częstych zapytań:
-- Check existing indexes first: SHOW INDEX FROM ps_cart;
ALTER TABLE ps_cart ADD INDEX idx_cart_date (date_add);
ALTER TABLE ps_connections ADD INDEX idx_conn_date (date_add);
ALTER TABLE ps_orders ADD INDEX idx_orders_ref (reference);
ALTER TABLE ps_product ADD INDEX idx_product_ref (reference);
Użyj EXPLAIN na wolnych zapytaniach, aby zweryfikować, czy indeksy są używane — jeśli kolumna „type” pokazuje „ALL”, oznacza to pełne skanowanie tabeli.
Strategie cache
Full page cache
Najbardziej spektakularna dostępna poprawa. Bez niego każde żądanie uruchamia setki plików PHP i ponad 100 zapytań (200-500ms). Z full page cache ta sama strona serwowana jest w 5-20ms.
Varnish to standard branżowy. nginx FastCGI cache jest prostszy, jeśli już używasz nginx:
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=PS:100m inactive=60m;
set $skip_cache 0;
if ($http_cookie ~* "PrestaShop-") { set $skip_cache 1; }
if ($request_uri ~* "/cart|/order|/my-account|/admin") { set $skip_cache 1; }
location ~ \.php$ {
fastcgi_cache PS;
fastcgi_cache_valid 200 10m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
}
Wyzwaniem jest inwalidacja cache — czyszczenie zakeszowanych stron, gdy zmieniają się produkty, ceny lub stany magazynowe. Ta złożoność sprawia, że wiele sklepów pomija full page caching.
Object caching i cache przeglądarki
Object caching (przez Redis) przechowuje kosztowne wyniki zapytań w pamięci. Mniej spektakularne niż full page cache (30-50% redukcji czasu zapytań), ale znacznie prostsze — PrestaShop obsługuje inwalidację automatycznie.
Cache przeglądarki — nagłówki mówią przeglądarkom odwiedzających, aby przechowały pliki statyczne lokalnie:
# Apache (.htaccess)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType font/woff2 "access plus 1 year"
</IfModule>
Typowe zabójcy wydajności
- Zbyt wiele modułów (50+): Każdy dodaje narzut autoloadera, callbacki hooków, CSS/JS i zapytania. Sklep z 30 modułami zawsze przewyższa sklep z 80. Nie istnieje coś takiego jak moduł o zerowym koszcie.
- Moduły ładujące zasoby wszędzie: Moduł popup, który działa tylko na stronie głównej, ale ładuje 150KB JavaScriptu na każdej stronie, to czyste marnotrawstwo. Sprawdź swój waterfall pod kątem nieistotnych zasobów modułów.
- Ciężkie slidery na stronie głównej: 3-5 obrazów w wysokiej rozdzielczości plus biblioteka JS = 1-5MB za komponent, z którym mniej niż 1% użytkowników wchodzi w interakcję po pierwszym slajdzie. Użyj pojedynczego statycznego obrazu głównego.
- Niezoptymalizowane własne szablony: Cały Bootstrap załadowany dla 3 komponentów, niezminifikowany CSS/JS, brak wymiarów obrazów, synchroniczne skrypty. Wymagaj audytów wydajności od twórców szablonów.
- Brakujące indeksy bazy danych: Zapytanie z właściwym indeksem trwa 10ms. Bez niego trwa 5 sekund — a nie zauważysz tego, dopóki ruch nie osiągnie szczytu.
Lista kontrolna monitorowania wydajności
Szybkie sprawdzenie (5 minut)
- Uruchom PageSpeed Insights na stronie głównej, stronie kategorii, stronie produktu
- Sprawdź, czy
_PS_MODE_DEV_jest ustawione nafalse - Potwierdź, że Smarty NIE jest ustawiony na „Wymuś kompilację”
- Sprawdź, czy CCC jest włączone
- Zweryfikuj, czy OPcache jest aktywny przez
phpinfo()
Miesięczna konserwacja (30 minut)
- Wyczyść porzucone koszyki w
ps_cart/ps_cart_product(starsze niż 3 miesiące) - Wyczyść
ps_log,ps_connections,ps_connections_page,ps_guest - Uruchom
OPTIMIZE TABLEna wyczyszczonych tabelach - Przejrzyj slow query log
- Odinstaluj nieużywane moduły
Przegląd kwartalny (2 godziny)
- Pełny test GTmetrix z wielu lokalizacji — porównaj z poprzednim kwartałem
- Przejrzyj Core Web Vitals w Google Search Console
- Audyt zasobów modułów pod kątem niepotrzebnych CSS/JS
- Sprawdź rozmiary obrazów — upewnij się, że nie ma zbyt dużych przesyłek
- Przejrzyj zużycie zasobów serwera (CPU, RAM, I/O dysku)
- Testuj na prawdziwym urządzeniu mobilnym, nie tylko w emulacji
- Zweryfikuj nagłówki cache przeglądarki
- Sprawdź logi błędów PHP (błędy zużywają zasoby)
Po każdym wdrożeniu
- Wyczyść cache PrestaShop
- Zresetuj OPcache, jeśli
validate_timestamps=0 - Uruchom szybki test PageSpeed w poszukiwaniu regresji
- Sprawdź konsolę przeglądarki pod kątem błędów JavaScript
- Przetestuj proces zamówienia od początku do końca
Zacznij tutaj
Optymalizacja wydajności to proces, nie cel. Zacznij od czterech elementów o największym wpływie: napraw konfigurację serwera, zoptymalizuj obrazy, wyłącz niepotrzebne moduły i wyczyść bazę danych. To samo rozwiązuje 80% problemów z wydajnością w większości sklepów PrestaShop.
Mierz przed i po każdej zmianie. Prowadź dziennik. Najlepsza optymalizacja to ta, którą zauważą Twoi klienci — szybsze ładowanie obrazów i responsywny checkout przekladają się bezpośrednio na zaufanie, satysfakcję i konwersje.
More guides available
Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.