Dla administratorów: pełny przebieg z dokładnymi liczbami i konfiguracją. Wersje i wartości: stan na listopad 2026.
Strony i stan wyjściowy
| Strona 1 | Strona 2 | Strona 3 |
| Problem po aktualizacji | ArgumentCountError: Too few arguments to function WP_Widget::__construct() w widgecie motywu z kreatora | błędy krytyczne w motywie i WPBakery 4.12 | Elementor ≥ 3.26 usunął Elementor\Core\Schemes, widgety motywu → HTTP 500 |
| Motyw | z kreatora, 86 plików + nieużywany drugi | 593 pliki (30 MB) + WPBakery 1 084 pliki (18 MB) | z własnym pakietem widgetów |
| Wtyczki | 9 (5 aktywnych) | 15 | 21 (m.in. Elementor Pro, Revolution Slider, The Grid, Yoast SEO) |
uploads | 45,4 MB + 7,3 MB kopii galerii | 92 MB | ok. 4,2 GB zdjęć |
| Baza | 1,27 MB, 22 tabele MyISAM | 265,8 MB (261,9 MB log audytu AIOWPS) | — |
Po przebudowie każda strona ma: WordPress 7.1.4, darmowy Elementor 4.3.5 jako jedyną wtyczkę, własny motyw
z Tailwind CSS 4 (strona 1: 27 plików, 0,5 MB; strona 2: 67 plików, 0,7 MB; strona 3: 7 własnych widgetów Elementora),
zdjęcia WebP z srcset, przekierowania 301 ze wszystkich starych adresów (?page_id=, ?portfolio_page=, /index.php/…,
stare pliki JPG), te same ID stron i załączników.
Metoda pomiaru
- Strony 1 i 2: stara i nowa wersja jednocześnie w naszym środowisku, identyczny stos:
wordpress:php8.3-apache,
mariadb:11.4 bez zmian w konfiguracji, ten sam php.ini, WORDPRESS_DEBUG wyłączony, opcache włączony,
automatyczne aktualizacje wyłączone. Przed pomiarem dwa żądania rozgrzewające na adres.
- Strona 3: na serwerze produkcyjnym, przez internet: stara 30.10.2026, nowa 02.11.2026, ten sam skrypt.
- Playwright (Chromium, 1440×900, świeży kontekst, cache wyłączony, przewinięcie do końca strony, User-Agent
zwykłego Chrome): liczba żądań, przesłane bajty, JS, żądania do obcych domen, TTFB, DOMContentLoaded,
load;
mediana z 3 przebiegów.
- Lighthouse 12.8.2, kategoria Performance: profil mobile (symulowane wolne 4G i słabszy telefon) i desktop,
User-Agent zwykłego Chrome, mediana z 3 przebiegów.
Wyniki
Strona 1, Lighthouse (mediana z 3):
| podstrona | mobile: wynik | mobile LCP | mobile CLS | desktop: wynik | desktop LCP | KB |
| strona główna | 67 → 100 | 3 458 → 1 653 ms | 0,806 → 0 | 99 → 100 | 689 → 405 ms | 450 → 145 |
| galeria | 72 → 99 | 7 056 → 2 180 ms | 0,115 → 0 | 95 → 100 | 1 532 → 488 ms | 1 177 → 228 |
| najcięższa | 71 → 98 | 11 930 → 2 402 ms | 0,115 → 0 | 91 → 100 | 2 031 → 562 ms | 3 808 → 407 |
Strona 1, Playwright (mediana z 3): żądania 19–41 → 10–20, przesłane 449–3 808 KB → 144–407 KB, JS 65–89 KB → 2 KB,
load 137–171 ms → 90–113 ms, TTFB 37–49 ms → 62–68 ms (patrz pułapki).
Strona 2, Lighthouse (mediana z 3):
| podstrona | mobile: wynik | mobile LCP | mobile TBT | mobile CLS | desktop: wynik | desktop LCP | KB |
| strona główna | 63 → 95 | 10 143 → 2 779 ms | 183 → 0 ms | 0 → 0 | 90 → 100 | 1 792 → 750 ms | 5 057 → 585 |
| siatka projektów | 50 → 81 | 13 886 → 5 106 ms | 120 → 0 ms | 0,324 → 0 | 92 → 99 | 1 681 → 1 005 ms | 2 968 → 744 |
| projekt (najcięższa) | 30 → 96 | 64 811 → 2 778 ms | 888 → 0 ms | 0,377 → 0 | 62 → 100 | 10 532 → 546 ms | 13 507 → 528 |
Strona 2, Playwright (mediana z 3): żądania 64–74 → 13–35, przesłane 2 376–13 429 KB → 474–927 KB, JS 807–810 KB →
5–106 KB, żądania do obcych domen 5–6 → 0, load 2 019–3 350 ms → 156–239 ms, TTFB 70–107 ms → 78–94 ms.
Strona 3 (produkcja, Playwright):
| podstrona | żądania | przesłane | JS | obrazy | load |
| strona główna | 113 → 33 | 7 647 → 540 KB | 422 → 120 KB | 6 783 → 285 KB | 658 → 600 ms |
| podstrona z galerią | 127 → 109 | 3 506 → 2 378 KB | 414 → 148 KB | 2 690 → 2 087 KB | 568 → 745 ms |
| kontakt | 104 → 21 | 920 → 254 KB | 402 → 111 KB | 9 → 15 KB | 1 014 → 526 ms |
Podstrona z galerią to jedyne miejsce, gdzie zdarzenie load przyszło później (745 wobec 568 ms); stary pomiar to jeden
przebieg innego dnia, więc tej różnicy nie uznajemy za rozstrzygniętą. Nowa strona 3, Lighthouse mobile: 98 / 91 / 98, LCP 2,3 / 3,4 / 2,3 s, TBT 0–13 ms, CLS 0 (dla starej brak pomiaru
Lighthouse; jej zdjęcia nie są już dostępne).
Co nie było oczywiste
- Pierwsze wejście aktualizuje stronę. Przy odtwarzaniu stron 1 i 2 wp-cron od razu podniósł rdzeń z 7.1.3 do 7.1.4
i część wtyczek; strona przez kilkanaście sekund zwracała 503 (
.maintenance). Bez AUTOMATIC_UPDATER_DISABLED
pomiar „przed” trafia na tryb konserwacji albo na inną wersję niż zastana. To ten sam mechanizm, który zepsuł strony.
- Baner cookies niewidoczny dla narzędzi. Cookie Notice z
bot_detection nie wypisuje banera dla User-Agenta
z „HeadlessChrome” ani dla curla. Pomiar domyślnym Playwrightem lub Lighthouse mierzy lżejszą stronę niż widzi człowiek;
wszystkie pomiary szły z User-Agentem zwykłego Chrome.
- Pozostałość po infekcji podwaja pracę serwera. Na stronie 1 nagłówek motywu (tylko dla niezalogowanych) ładował
<script src=/wp-includes/js/stat096.php>; pliku nie było, więc każde wyświetlenie robiło drugie pełne uruchomienie
WordPressa (strona 404, ok. 25 KB HTML pobierane jako skrypt). Przy przebudowie znaleziony też webshell w uploads.
- Te same zdjęcia trzy razy. NextGEN trzymał własne kopie (z plikami
_backup) identyczne co do MD5 z biblioteką
mediów, a druga wtyczka galerii czwartą kopię, nigdzie nieużywaną, choć jej CSS i JS ładowały się na każdej stronie.
- Brak
srcset przy obrazkach bez klasy wp-image-N. Obrazy wstawione z tymczasowym id __wp-temp-img-id
nie dostają wariantów, więc miniatura 401 px pobierała oryginał (10 zdjęć, 3,7 MB na jednej podstronie). Na stronie 2
zdjęcie 6240×4160 (10,3 MB) w całości: stąd mobile LCP 64,8 s.
- Wariant 400 px to za mało dla pola 401 px. Przeglądarka wybierała 800 px; pionowe zdjęcia bez wariantu pośredniego
ładowały oryginał. Rozmiary
medium 402 px i medium_large 804 px obcięły zdjęcia jednej podstrony z 838 do 381 KB.
- Elementor kosztuje po stronie serwera. TTFB strony 1 wzrósł z 37–49 ms do 62–68 ms: lżejsza strona jest
generowana dłużej, bo Elementor ładuje swój rdzeń przy każdym żądaniu. Dla odwiedzającego wygrywa i tak nowa wersja
(mniej danych, brak blokującego JS), ale bez pamięci podręcznej stron różnica na serwerze jest realna.
- Elementor domyślnie ładuje jQuery i ok. 230 KB JS nawet na stronie bez interakcji. Własny lightbox (natywny
<dialog>, 4,8 KB z menu) i warunkowe wyłączenie frontendu Elementora na stronach bez widgetów z JS: 262–373 KB → 5 KB.
Gdy redaktor doda karuzelę albo zakładki, skrypty wracają same.
- Elementor 4 z domyślnymi eksperymentami dokłada CSS edytora V4 (beta), inline JS leniwego ładowania teł
i
<meta name="generator"> z listą funkcji; wyłączone opcjami.
- Tailwind
@layer przegrywa z CSS Elementora. Style w @layer components, a CSS Elementora poza warstwami, więc
wygrywa Elementor niezależnie od specyficzności (np. .elementor img { height: auto } psuło zdjęcia hero). Komponenty
motywu trzeba trzymać poza @layer.
- Marginesy nie zapadają się w kontenerach Elementora (flex). Układy starych motywów opierały się na zapadaniu
marginesów i komórkach tabel; odtworzenie 1:1 wymagało
display: flow-root i paddingów kontenerów.
- Fonty „lokalne” ładowane z obcej domeny. Wtyczka do lokalnych fontów zapisała CSS z adresem względnym protokołu
(
//www.<domena>/wp-content/uploads/omgf/…); search-replace w bazie tego nie zmienia, bo to plik.
- Hotlinki do serwera demo motywu. Tło stopki i wzór w sekcji strony głównej ładowały się z serwera
demonstracyjnego producenta motywu; wzór był widoczny tylko dlatego, że brakowało właściwego obrazu tła.
- CAPTCHA logowania ustawiała
PHPSESSID każdemu odwiedzającemu, a wtyczka map ładowała Google Maps JS na każdej
podstronie, choć mapy na stronie nie było. Razem 5–7 obcych domen przy pierwszym wejściu; po przebudowie 0 ciasteczek,
0 danych w przeglądarce, 0 obcych domen przed zgodą (mapy ładują się dopiero po kliknięciu).
- Nie wszystko wyszło idealnie. Siatka projektów strony 2 ma na telefonie wynik 81 i LCP 5,1 s: dużo kafelków
ze zdjęciami nad zgięciem ekranu. To miejsce na kolejną optymalizację (mniejsze miniatury, priorytet pierwszego kafelka).
Rozwiązanie w skrócie
- Odtworzenie stanu zastanego z archiwum, paczki poprawek i zrzutu bazy, automatyczne aktualizacje wyłączone.
- Inwentaryzacja stron, menu, typów treści, wtyczek (co z nich faktycznie jest używane), zdjęć i bazy.
- Czysty WordPress, darmowy Elementor, własny motyw (Tailwind, Fontsource, Lucide, własne widgety Elementora), import
treści skryptami z zachowaniem ID, konwersja zdjęć do WebP (maks. 1600–2048 px) z wariantami.
- Porównanie zrzutów każdej podstrony (desktop 1440×900, mobile 390×844) do wizualnej równoważności (±3 do ±60 px wysokości).
- Kontrola: wszystkie strony 200, przekierowania 301, formularze, audyt świeżego odwiedzającego, log PHP bez błędów.
Rezultaty
| Etykieta | Wartość |
| Lighthouse mobile, najcięższa podstrona | 30 → 96 (strona 2), 71 → 98 (strona 1) |
| Mobile LCP, najcięższa podstrona | 64,8 s → 2,8 s (strona 2), 11,9 s → 2,4 s (strona 1) |
| Przesłane dane, najcięższa podstrona | 13,4 MB → 0,5 MB (strona 2), 3,8 MB → 0,4 MB (strona 1) |
| Strona główna strony 3 (produkcja) | 113 żądań i 7,6 MB → 33 żądania i 0,5 MB |
| JavaScript na podstronie | 807 KB → 5–106 KB (strona 2), 65–89 KB → 2 KB (strona 1) |
| Wtyczki | 9 / 15 / 21 → 1 (darmowy Elementor) |
| Baza danych | 265,8 MB → 1,4 MB (strona 2) |
| Obce domeny i ciasteczka przy pierwszym wejściu | 5–7 domen, PHPSESSID → 0 |
Wnioski
- Strona, która psuje się po każdej aktualizacji, to zwykle stary, rozbudowany motyw z dodatkami, a nie WordPress.
Przebudowa 1:1 na jedną wtyczkę usuwa przyczynę, a nie objaw.
- Najwięcej dały podstawy: właściwe rozmiary zdjęć z
srcset, brak nieużywanych wtyczek ładujących swoje pliki na każdej
stronie i brak zewnętrznych skryptów.
- Elementor ma swój koszt (serwer, jQuery, CSS); da się go ograniczyć, ale warto mierzyć, a nie zakładać.
- Pomiar trzeba robić uczciwie: ten sam stos dla obu wersji, wyłączone aktualizacje, User-Agent zwykłej przeglądarki.