Płatny moduł PrestaShop, który znaleźliśmy na sklepie klienta, wczytywał ozdobną czcionkę z zewnętrznego CDN-a na każdej stronie — na stronie głównej, na każdej kategorii, na każdym produkcie, w koszyku, na checkoutcie. Czcionka była używana w dokładnie jednym miejscu: na własnym ekranie ustawień modułu, głęboko w panelu administracyjnym, do którego zaglądała mniej więcej jedna osoba w całej firmie.

Oto ile ta niedbałość faktycznie kosztowała, zmierzone na działającej stronie głównej. Moduł dodał jedną nową domenę zewnętrzną, trzy dodatkowe żądania na stronę (arkusz stylów i dwa pliki czcionek) oraz około 159 KB danych, których nie potrzebowała przeglądarka żadnego odwiedzającego. Ponieważ arkusz stylów znajdował się w sekcji <head> strony, blokował renderowanie: każdy nowy odwiedzający czekał na odpytanie DNS i uzgodnienie TLS z serwerem, o którym właściciel sklepu nigdy wcześniej nie słyszał, zanim strona mogła się w pełni wyświetlić. Na spowolnionym połączeniu mobilnym Largest Contentful Paint pogorszył się z 2,4 do 2,9 sekundy, a wynik wydajności Lighthouse spadł z okolic niskiej dziewięćdziesiątki do połowy osiemdziesiątki. Nic katastrofalnego. Po prostu podatek, po cichu naliczany przy każdym wczytaniu strony, na zawsze, za czcionkę, której nikt spoza administracji nigdy nie widział.

Zasięg rażenia obejmował cały sklep; funkcja dotyczyła jednego ekranu. Ta rozbieżność — między tym, czego moduł dotyka, a tym, do czego naprawdę służy — jest głównym tematem tego artykułu. Ograniczyliśmy zasób tak, by czcionka wczytywała się wyłącznie na stronie, która jej używa, i liczby wróciły do poziomu wyjściowego. Poprawka zajęła jedno popołudnie. Wykrycie, że problem w ogóle istnieje, wymagało przeglądarki i nawyku.

Porównanie wydajności strony głównej PrestaShop przed i po: płatny moduł dodający czcionkę z zewnętrznego CDN-a zwiększył liczbę domen zewnętrznych, wagę strony i Largest Contentful Paint; ograniczenie zasobu przywróciło poziom wyjściowy

Ten moduł nie był złośliwym oprogramowaniem. I o to właśnie chodzi. Nikt nie próbował nikomu zaszkodzić. Programista chciał, żeby jego strona ustawień ładnie wyglądała, sięgnął po czcionkę i wkleił fragment kodu CDN, który dała mu strona internetowa czcionki — a następnie, z tego samego odruchu kopiuj-wklej, zarejestrował ten sam arkusz stylów również na globalnym hooku nagłówka front-office, mimo że korzystała z niego wyłącznie strona ustawień. Każda decyzja z osobna była mała i rozsądna. W sumie dała ogólnosklepową regresję wydajności, której żadne „przecież to mały moduł” by nie przewidziało. Wystarczyła niedbałość. Zwykle wystarcza.

Jeśli chce Pan zobaczyć, jak niewiele trzeba, oto kształt tego błędu — zrekonstruowany, a nie oryginalny kod dostawcy. Sam ekran ustawień doskonale wczytuje tę czcionkę w panelu administracyjnym; szkodę wyrządziła druga, zbędna linia, która dodatkowo rejestrowała ten sam arkusz stylów na hooku nagłówka front-office — tym, który uruchamia się na każdej stronie sklepu, gdzie nic z niego nie korzysta:

// Runs on EVERY page of the storefront — home, category, product, checkout
public function hookDisplayHeader($params)
{
    // …yet nothing on the storefront uses this font — the settings screen loads it itself.
    $this->context->controller->addCSS(
        'https://3p-cdn.net/fancy-display/style.css'  // third-party, render-blocking
    );
}

Nie ma tu niczego złośliwego; to garść linii, które robią dokładnie to, co mówią. Problem w tym, że ten hook nie ma nic wspólnego z ekranem ustawień, dla którego przeznaczona jest czcionka. displayHeader renderuje się w sklepie, więc czcionka przeznaczona dla jednej strony administracyjnej jest pobierana przez każdego kupującego — na darmo. Rozwiązaniem jest całkowite usunięcie rejestracji po stronie sklepu i pozostawienie panelowi administracyjnemu wczytywania czcionki tam, gdzie jest ona faktycznie używana:

// The storefront never shows this font, so the front-office hook loads nothing.
public function hookDisplayHeader($params)
{
    return;
}

// It loads only on this module's own settings screen in the back office —
// self-hosted, so no third-party domain and no extra DNS + TLS round-trip.
public function hookDisplayBackOfficeHeader($params)
{
    if (Tools::getValue('configure') !== $this->name) {
        return; // every other admin page pays nothing either
    }
    $this->context->controller->addCSS($this->_path.'views/css/fancy-display.css');
}

Ta sama funkcja, ta sama czcionka — sklep nie wczytuje już niczego, czego nie używa, a ogólnosklepowy podatek znika wraz z domeną zewnętrzną. Ta różnica między dwiema wersjami to cała przepaść między modułem, który trzyma się swojego pasa, a takim, który po cichu obciąża każdą stronę funkcją, której prawie nikt nie widzi. Nikt nie musiał być niedbały celowo.

Problem w tym, że moduły udają aplikacje

Większość sprzedawców myśli o modułach tak, jak myśli o aplikacjach na telefon. Aplikacja jest odizolowana: działa we własnym ogrodzonym obszarze, nie może sięgnąć do innych aplikacji, a jeśli jej Pan nie lubi, to ją Pan usuwa i telefon jest dokładnie taki, jak wcześniej. Ten model myślenia jest wygodny, a w przypadku PrestaShop całkowicie błędny.

Moduł PrestaShop nie jest odizolowaną aplikacją. To nieizolowany kod PHP działający z pełnymi uprawnieniami Pana sklepu. Po zainstalowaniu i włączeniu może wpiąć się w każdą renderowaną stronę, odczytywać i zapisywać dowolną tabelę w bazie danych — zamówienia, klientów, ceny, konfigurację — rejestrować nadpisania (overrides), które po cichu zastępują domyślne zachowanie systemu, umieszczać pliki w Pana szablonie, dodawać kolumny i tabele, planować zadania w tle oraz wykonywać w Pana imieniu wywołania do usług zewnętrznych. To nie jest gość w ogrodzonym obszarze. To pracownik z kluczami do całego budynku, którego zatrudnił Pan, klikając „instaluj”.

Moduł to nie funkcja, którą się włącza. To kod, któremu oddaje Pan klucze do swojego sklepu. Pytanie nigdy nie brzmi „czy ta funkcja jest fajna” — brzmi „czy ufam temu kodowi we wszystkim, co mój sklep potrafi zrobić”.

Nic z tego nie jest wadą PrestaShop. Ta moc jest właśnie powodem, dla którego platforma jest na tyle rozszerzalna, by prowadzić na niej poważny biznes. Ale oznacza to, że model bezpieczeństwa, który nosi Pan w głowie — model aplikacji — nie chroni Pana przed niczym.

Ujmijmy to konkretnie: jeden włączony moduł może sięgnąć do tego wszystkiego naraz — wpina się w każdą renderowaną stronę, dodaje i zmienia tabele bazy danych, umieszcza pliki nadpisań na klasach systemu, edytuje Pana szablon, wczytuje zasoby w całej witrynie, planuje zadania w tle, odczytuje i zapisuje Pana zamówienia oraz dane klientów, a także wykonuje wywołania do usług zewnętrznych. Aplikacja na Pana telefonie nie może zrobić nic z tego telefonowi. Moduł PrestaShop może zrobić to wszystko Pana sklepowi — dlatego „po prostu zainstaluj i zobacz” to większa decyzja, niż na to wygląda.

Diagram tego, czego moduł PrestaShop może dotknąć po włączeniu: hooki na każdej stronie, tabele bazy danych, nadpisania systemu, pliki szablonu, zasoby front-office, zadania cron, zamówienia i dane klientów oraz usługi zewnętrzne

„Działało w moim sklepie testowym” — tu zaczynają się kłopoty

Najdroższe cztery słowa w tworzeniu modułów to „u mnie działało”. Programista buduje moduł, instaluje go na czystym sklepie testowym, klika tu i tam, widzi, że działa, i wypuszcza. Kłopot w tym, że czysty sklep testowy nie ma nic wspólnego z prawdziwym sklepem.

Pana prawdziwy sklep ma własny szablon, który nadpisuje pliki template’ów, jakie moduł zakładał. Może działać w trybie multishop, w którym moduł testowany wyłącznie na sklepie 1 po cichu psuje się na sklepie 2. Działa na konkretnej wersji PHP, która może być starsza lub nowsza niż ta, którą miał programista. Ma dziesiątki innych modułów już wpiętych w te same strony, konkurujących o ten sam wynik. Ma prawdziwy ruch, warstwę cache, działający checkout przyjmujący prawdziwe pieniądze i — co najważniejsze — kiedyś zostanie zaktualizowany do nowej wersji PrestaShop, względem której modułu nigdy nie testowano. „Zadziałało raz, na jednym sklepie, na jednej wersji” niczego nie gwarantuje. Moduł musi działać dalej w tym wszystkim, przez lata. To zasadniczo trudniejsza obietnica niż „to działa”, a większość ryzyka tkwi właśnie w tej różnicy. To także powód, dla którego jakość modułów liczy się bardziej niż ich ilość, i ukryta połowa tego, co naprawdę spowalnia PrestaShop.

Co przetrwa, gdy wyłączasz lub odinstalowujesz moduł

Oto przekonanie, które wyrządza najwięcej szkody: „jeśli spowoduje problem, to po prostu go odinstaluję i wszystko wróci do normy”. Czasem to prawda. Często nie, a tę różnicę warto rozumieć precyzyjnie — bo pewna siebie wersja tego założenia to sposób, w jaki sklepy po cichu ulegają uszkodzeniu.

Wyłączenie modułu zatrzymuje uruchamianie jego hooków w czasie działania. To naprawdę pomaga: moduł przestaje wstrzykiwać swoje zasoby i uruchamiać swój kod na każdej stronie, więc bieżący problem z wydajnością lub wyświetlaniem zwykle od razu ustępuje. Wyłączenie to właściwy pierwszy ruch w sytuacji awaryjnej. Ale wyłączenie nie sięga wstecz i nie cofa niczego, co moduł już zrobił.

Odinstalowanie idzie dalej i uruchamia własną procedurę sprzątającą modułu — a ta procedura usuwa tylko to, co jej autor zadał sobie trud zakodować do usunięcia. Co nie wraca niezawodnie samo z siebie:

  • Zmiany w bazie danych i konfiguracji. Nowe tabele, nowe kolumny i wiersze konfiguracji mogą zostać. Niektóre moduły celowo zachowują Pana dane przy odinstalowaniu, aby nie stracił Pan ustawień przy ponownej instalacji — to rozsądny wybór, ale tylko jeśli o tym informują.
  • Dane zamówień i klientów. Wszystko, co zapisano w Pana zamówieniach, fakturach lub kartotekach klientów podczas normalnej pracy, to Pana żywe dane biznesowe. Odinstalowanie modułu tego nie usuwa i nie powinno — ale może pozostawić te dane w formie, którą rozumiał tylko ten moduł.
  • Nadpisania i zmiany w szablonie. Pliki umieszczone w /override lub w Pana szablonie mogą przeżyć moduł. Nieaktualne nadpisanie pozostawione po odinstalowaniu to klasyczne źródło „mój sklep się zepsuł i nic, co wyłączyłem, tego nie naprawiło”.
  • Integracje zewnętrzne. Dane, które moduł wysłał do usługi zewnętrznej — do feedu, CRM-a, platformy analitycznej czy marketingowej — już nie są pod kontrolą Pana sklepu. Odinstalowanie niczego po drugiej stronie nie zmienia.

Zatem trafne zdanie brzmi: wyłączenie tamuje krwawienie, ale odinstalowanie nie cofa zapisów w bazie danych, zmian konfiguracji, danych zamówień i klientów, nadpisań, zmian w szablonie ani wywołań zewnętrznych, których moduł już dokonał. „Po prostu go odinstaluję” to plan na funkcję. To nie jest plan na jej ślad.

Warto wyobrazić sobie trzy stany obok siebie. Wyłączenie zatrzymuje działanie modułu. Odinstalowanie uruchamia jego procedurę sprzątającą. Ale cała kolumna rzeczy — dane zapisane w Pana zamówieniach i kartotekach klientów, konfiguracja, nadpisania, zmiany w szablonie oraz wszystko, co już wysłano do usługi zewnętrznej — przetrwa oba te działania, chyba że autor modułu napisał kod, by je odwrócić, a Pan potwierdził, że tak się stało. To ta ostatnia kolumna zaskakuje ludzi w najgorszym możliwym momencie.

Porównanie tego, co usuwa wyłączenie, a co odinstalowanie modułu PrestaShop, oraz danych zamówień, konfiguracji, nadpisań, zmian w szablonie i wywołań zewnętrznych, które przetrwają oba

My też popełniliśmy ten błąd

Nieuczciwie byłoby pisać to wszystko tak, jakby przydarzało się to tylko innym. Tak nie jest. Tworzymy i sprzedajemy moduły PrestaShop na życie i popełniliśmy ten sam rodzaj błędu.

W jednym z naszych własnych modułów skrypt front-office, którego potrzebowała jedna funkcja, został zarejestrowany na hooku uruchamiającym się na każdej stronie, zamiast wyłącznie na kontrolerach, na których ta funkcja faktycznie się pojawia. Funkcjonalnie wszystko działało, więc przeszedł przegląd i został wypuszczony. Dopiero audyt wydajności kilka miesięcy później — ten sam rodzaj audytu, o którym mowa w tym artykule — wychwycił mały skrypt wczytywany w całej witrynie bez powodu na stronach, które nigdy go nie używały. Koszt nie był dramatyczny: kilka kilobajtów i odrobina czasu parsowania na każdej stronie, w całym katalogu, dopóki tego nie naprawiliśmy. Ale był realny, był nasz, a „to działało” przepuściło go prosto dalej.

Tym, co się zmieniło, nie był wykład o większej staranności. Zamieniliśmy to w pytanie, na które przegląd musi odpowiedzieć dla każdego zasobu i każdego hooka: czy to naprawdę musi być globalne, czy należy do stron, które z tego korzystają? Blizna staje się regułą, a reguła wychwytuje następny przypadek. To uczciwa wersja jakości — nie „nigdy nie popełniamy błędów”, lecz „zbudowaliśmy coś, co wychwytuje je, zanim zrobi to Pan”. To ta sama dyscyplina, dzięki której doprowadziliśmy prawdziwy sklep z ponad 80 modułami do wyniku 99 w PageSpeed: nie mniej modułów, lecz moduły, które trzymają się swojego pasa — co jest całą ideą projektową naszego pakietu Performance Revolution.

To czy AI nie jest tu złoczyńcą?

Mógłby Pan oczekiwać, że dostawca modułów zakończy to obwinianiem AI — tanim kodem generowanym przez AI zalewającym rynek bylejakością. Nie zrobimy tego, bo byłoby to zarazem niesprawiedliwe i hipokrytyczne. Sami intensywnie korzystamy z inżynierii wspieranej przez AI. Właśnie dlatego nie oceniamy modułu po tym, czy dotknęło go AI.

AI jest akceleratorem. Przyspiesza dobrą inżynierię i przyspiesza niedbałą inżynierię, a nie ma zdania na temat tego, którą z nich Pan uprawia. Błąd z czcionką na każdej stronie wyprzedza obecną falę AI o dekadę; niejeden pośpieszny człowiek napisał ich mnóstwo. Tym, co odróżnia moduł, któremu można zaufać, od takiego, któremu nie można, nigdy nie było narzędzie autora. Jest nim zarządzanie: czy jest wyznaczony właściciel, czy kod jest recenzowany, czy jest testowany, czy jest utrzymywany w zgodności w miarę rozwoju PrestaShop, czy jego zmiany da się cofnąć, czy mieści się w swoim budżecie wydajności, czy ktoś będzie go utrzymywał w przyszłym roku. Te pytania są dokładnie tak samo zasadne, niezależnie od tego, czy kod napisał człowiek, wygenerował model, czy — jak to dziś normalne — napisali go człowiek i model razem. Własność, przegląd i testy to sedno sprawy. Autorstwo to odwrócenie uwagi.

Oceń nas tym samym testem

My też sprzedajemy moduły, więc łatwo byłoby odczytać to wszystko jako „kupuj u nas zamiast tego”. Niech Pan nie wierzy nam na słowo — to cały duch tej rzeczy. Uczciwym ruchem jest przyłożenie do każdego dostawcy, nas włącznie, tej samej miary, a dobra wiadomość jest taka, że większość ważnych sprawdzeń nie wymaga żadnej znajomości PHP. Może je Pan przeprowadzić z przeglądarki na kopii testowej swojego sklepu: zainstalować moduł, otworzyć kartę Sieć (Network) w przeglądarce na stronie głównej (a nie na stronie modułu) i policzyć, co się zmieniło.

Spisaliśmy całą procedurę jako prostą, napisaną zwykłym językiem instrukcję — jak sprawdzić moduł PrestaShop, zanim zainstaluje się go na działającym sklepie — i traktujemy ją jako narzędzie do użycia przeciwko naszemu katalogowi równie chętnie, co czyjemukolwiek. Jeśli wolałby Pan, aby ktoś zrobił to za Pana, właśnie tym są nasze audyty wydajności i audyty bezpieczeństwa, a nasze darmowe skanowanie bezpieczeństwa to bezkosztowy punkt startu. Niech Pan obróci tę listę kontrolną przeciwko nam. Wolelibyśmy, żeby Pan to zrobił.

Najczęstsze pytania

Czy odinstalowanie modułu usuwa wszystko, co utworzył?

Nie — nie w sposób niezawodny. Odinstalowanie uruchamia własną procedurę sprzątającą modułu, która usuwa jedynie to, co jego autor zakodował do usunięcia. Tabele bazy danych, wiersze konfiguracji, pliki w /override, zmiany w szablonie i wszelkie dane już wysłane do usługi zewnętrznej mogą przetrwać. Nie powinno ono także nigdy usuwać Pana zamówień ani kartotek klientów, bo to Pana żywe dane biznesowe. Niech Pan zakłada, że odinstalowanie sprząta funkcję, a nie cały ślad.

Czy jeden moduł naprawdę może spowolnić cały mój sklep?

Tak. Gdy moduł wczytuje zasoby lub uruchamia kod na globalnym hooku — takim, który odpala się na każdej stronie — ten koszt płaci każda strona, w tym Pana strona główna i checkout, nawet strony, na których funkcja w ogóle się nie pojawia. Dokładnie tak czcionka przeznaczona dla jednego ekranu administracyjnego skończyła, obciążając cały sklep.

Czy moduł jest niebezpieczny tylko dlatego, że pomogło go napisać AI?

Nie. AI jest akceleratorem, a nie werdyktem. O zaufaniu do modułu decydują własność, przegląd, testy, zgodność, odwracalność i dyscyplina wydajności — a te dotyczą go niezależnie od tego, czy kod napisał człowiek, model, czy oboje. Niech Pan ocenia zarządzanie, a nie autorstwo.

Jak właściwie sprawdzić moduł, zanim go zainstaluję?

Na kopii testowej zainstaluj go i obserwuj, co się zmienia: nowe żądania do serwisów zewnętrznych na karcie Sieć strony głównej, nowe tabele bazy danych, czy checkout nadal działa oraz czy odinstalowuje się czysto. Spisaliśmy pełną instrukcję krok po kroku jako jak sprawdzić moduł PrestaShop, zanim się go zainstaluje.

Najlepsze moduły są nudne

Po wszystkich tych opowieściach z pola bitwy wniosek jest niemal antyklimaktyczny i o to właśnie chodzi. Dobry moduł jest nudny. Robi tę jedną rzecz, którą reklamował. Jego zasoby wczytują się tylko tam, gdzie są używane. Dotyka tylko tych danych, których potrzebuje, mówi Panu, co zachowuje, i sprząta to, co może. Przeżywa Pana kolejną aktualizację PrestaShop bez dramatów. A najprawdziwszym znakiem jego jakości jest to, że sześć miesięcy po instalacji zupełnie zapomniał Pan, że tam jest.

Ekscytacja w module to niemal zawsze odgłos czegoś, co idzie nie tak, na stronie, której nigdy nie powinien był dotknąć. Nudny to cel. Nudny to sposób, w jaki „to po prostu działa” wygląda naprawdę od środka — i warto tego celowo sprawdzać, zanim wprowadzi się nieznajomy z kluczami do całego Pana sklepu.

Udostępnij ten wpis:
David Miller

David Miller

Founder, mypresta.rocks

David Miller to specjalista PrestaShop z ponad dekadą praktycznego doświadczenia i założyciel mypresta.rocks — studia programistycznego z Tychów. Tworzy i utrzymuje katalog 152 modułów PrestaShop — w tym 21 pakietów „Revolution" obejmujących SEO, checkout, bezpieczeństwo, wydajność, marketing, wyszukiwanie, wsparcie i operacje magazynowe — które każdego dnia usprawniają realne sklepy, testowanych na PrestaShop 1.7.8, 8.x i 9.x. Sprawuje również opiekę nad sklepami produkcyjnymi generującymi miliony rocznego obrotu, dlatego jego pracę ocenia się po realnej sprzedaży, a nie po wersjach demo. Jego doświadczenie obejmuje pełen zakres e-commerce — wydajność, bezpieczeństwo, SEO i marketing — oraz wykracza poza PrestaShop, sięgając WooCommerce, Shopify i systemów tworzonych na zamówienie. Na blogu pisze o technicznej stronie PrestaShop: co platforma naprawdę robi pod maską, co psuje się na produkcji i które rozwiązania faktycznie się sprawdzają.

Spodobał Ci się ten artykuł?

Otrzymuj nasze najnowsze porady, przewodniki i aktualizacje modułów prosto na swoją skrzynkę.

Komentarze

Brak komentarzy. Bądź pierwszy!

Bądź pierwszy: zadaj pytanie albo podziel się przydatną opinią.

Ładowanie...
Do góry