Przejdź do treści
Warsztat

121 pomiarów Core Web Vitals. Dwie moje najlepsze hipotezy pomiary odrzuciły

Ten sam adres bez zmiany w kodzie dawał od 60 do 96 punktów. Dwie podręcznikowe optymalizacje wdrożyłem, zmierzyłem i wycofałem. Oto liczby.

6 min czytania
121 pomiarów Core Web Vitals. Dwie moje najlepsze hipotezy pomiar odrzucił

👁 115 przeczytań

// w skrócie
  • Pojedynczy pomiar Lighthouse nic nie znaczy - ten sam adres bez żadnej zmiany w kodzie dawał wyniki od 60 do 96 punktów.
  • Sklejenie plików CSS w jeden plik pogorszyło TBT z 76 ms do 372 ms, bo jedno zadanie 69 KB blokuje wątek główny nieprzerywalnie.
  • Prawdziwym źródłem rozrzutu był stos reklamowy: po jego zablokowaniu rozrzut FCP spadł z 22% do 0,7%, a wynik ustabilizował się na 77/77.

Optymalizowałem ten serwis przez kilka dni, robiąc po każdej zmianie serię pomiarów Lighthouse zamiast jednego przebiegu. Efekt był upokarzający: dwie z moich najlepszych hipotez okazały się szkodliwe, a prawdziwego winowajcę znalazłem dopiero wtedy, gdy przestałem wierzyć w pojedynczy wynik. 121 pomiarów w dziewięciu seriach. Oto co z nich wyszło.

Trzy wnioski w jednym akapicie

1. Jeden pomiar Lighthouse nic nie znaczy - ten sam adres dawał mi wyniki od 60 do 96 punktów bez żadnej zmiany w kodzie. 2. Sklejenie plików CSS w jeden, czyli rada z każdego poradnika, pogorszyło TBT z 76 do 372 ms. 3. Winowajcą rozrzutu nie był mój kod, tylko stos reklamowy - po zablokowaniu domen reklamowych wynik ustabilizował się na 77/77 z rozrzutem FCP na poziomie 0,7% zamiast 22%.

Aktualna lista kursów AI

Zestawienie odświeżane automatycznie raz na dobę: ceny, liczba wykładów i oceny prosto z katalogu sprzedawcy. Nowości i bestsellery na górze.

Otwórz zestawienie →

Zasada zero: mierz serię, nie pojedynczy przebieg

To brzmi banalnie, ale prawie nikt tego nie robi - i dlatego prawie wszystkie „optymalizacje” w internecie to przypadek.

Uruchomiłem Lighthouse dziesięć razy z rzędu na niezmienionym adresie. Wyniki rozjechały się od 60 do 96 punktów. Gdybym zmienił cokolwiek w kodzie i trafił na przebieg 96 po zmianie i 60 przed, ogłosiłbym sukces. Gdyby wyszło odwrotnie, wycofałbym dobrą poprawkę.

Pro tip: minimum pięć przebiegów na wariant, porównuj mediany i zawsze podawaj pełny zakres. Jeśli zakresy przed i po zachodzą na siebie, nie masz wyniku - masz szum.

Hipoteza 1, odrzucona: sklejanie CSS w jeden plik

Klasyczna rada: mniej żądań HTTP, więc połącz arkusze. Zbudowałem paczkę z kilku plików CSS motywu, sprawdziłem poprawność ścieżek względnych i kolejności importów, wdrożyłem. Pomiar:

Wskaźnik na stronie wpisuPrzedPo sklejeniu
TBT (blokowanie wątku głównego)76 ms372 ms
Czas styleLayout700 ms1018 ms

Dlaczego to nie zadziałało: pięć osobnych arkuszy to pięć krótkich zadań parsowania, które przeglądarka może przeplatać z innymi. Jeden arkusz 69 KB to jedno długie zadanie, którego nie da się przerwać - a długie zadania to dokładnie to, co mierzy TBT. Zmniejszyłem liczbę żądań i pogorszyłem odczucie płynności.

Pro tip: przy HTTP/2 liczba żądań przestała być problemem. Sklejanie plików to porada z czasów HTTP/1.1 i dziś potrafi zaszkodzić.

Hipoteza 2, odrzucona: odroczenie zapytań w tle

Strona sklepu wysyłała kilka zapytań AJAX przy starcie. Odroczyłem je przez requestIdleCallback z limitem czasu 3000 ms - podręcznikowe rozwiązanie. Pomiar:

  • TBT sklepu: 64 ms → 265 ms
  • Start zapytań przesunął się z przedziału 183-1329 ms na 383-2411 ms

Dlaczego to nie zadziałało: limit czasu 3000 ms sprawił, że przeglądarka odpaliła wszystkie odroczone zapytania jedną serią - i to dokładnie w oknie, w którym liczony jest TBT. Zamiast rozłożyć pracę, zebrałem ją w jeden korek.

Pro tip: requestIdleCallback z krótkim limitem czasu to nie jest „zrób to później”. To jest „zrób to później, ale na pewno”. Bez limitu albo z bardzo długim zachowuje się inaczej.

Co zadziałało i dlaczego

Jedna linijka, która skasowała 70 ms wymuszonego przeliczenia układu

Skrypt odczytywał pozycję elementu i od razu ją zmieniał. To powoduje wymuszone przeliczenie układu - przeglądarka musi przerwać wszystko i policzyć geometrię strony. Lighthouse wskazywał 70-75 ms w jednej linii.

Poprawka to jedna linijka:

if (window.requestAnimationFrame) requestAnimationFrame(miejsce); else miejsce();

Odczyt przenosi się do momentu, w którym przeglądarka i tak przelicza układ. Koszt spada do zera, a kod robi dokładnie to samo.

Wyrzucenie z krytycznej ścieżki tego, czego strona nie używa

Arkusz szablonów ważył 75 094 bajty i ładował się na każdej podstronie, mimo że większość stron nie używa żadnego z tych szablonów. Wersja podstawowa to 9 708 bajtów - czyli 87% wagi szło na darmo. Podobnie jQuery, ładowane mimo braku jakiegokolwiek konsumenta.

Pro tip: zanim zaczniesz minifikować, sprawdź, czy plik jest w ogóle potrzebny na tej stronie. Usunięcie bije kompresję każdego dnia.

Prawdziwy winowajca: stos reklamowy

Nie przepłacaj za te subskrypcje

Prowadzę sklep z rocznymi dostępami do narzędzi AI - te same konta, o których piszę wyżej, tylko taniej niż w cenniku producenta.

Zobacz, co jest dostępne

Po odrzuceniu obu hipotez zadałem inne pytanie: skąd bierze się rozrzut 60-96 punktów. Zablokowałem domeny reklamowe i zgody i powtórzyłem serię:

Z reklamamiBez reklam
Wynik wydajności60-96, dwubiegunowystabilne 77/77
Rozrzut FCP22%0,7%
TBTzmienny0
Waga stosu445-467 KB

Wniosek był brutalny: przez kilka dni optymalizowałem kod, który odpowiadał za ułamek problemu. Rozrzut brał się z zewnętrznych skryptów, na które nie mam wpływu i których nie usunę, bo finansują serwis.

Pro tip, najważniejszy z całego tekstu: zanim zoptymalizujesz cokolwiek, zmierz, ile z wyniku pochodzi od Ciebie, a ile od zewnętrznych skryptów. Zrób serię z zablokowanymi domenami stron trzecich. Jeśli różnica jest duża, Twój realny sufit jest znacznie niżej, niż myślisz - i lepiej to wiedzieć przed trzema dniami pracy niż po.

Dwie pułapki narzędzi, na które trafiłem przy okazji

Pingdom potrafi kłamać o kompresji

Raport twierdził, że serwer nie kompresuje odpowiedzi. Sprawdziłem bezpośrednio: serwer wysyła br i zstd, a gdy poprosić wprost o gzip, oddaje stronę główną w 71 306 bajtach zamiast 289 394 nieskompresowanych. Narzędzie po prostu nie deklarowało obsługi nowszych algorytmów. Nagłówki wygasania też były na miejscu.

Czyszczenie całego cache potrafi zepsuć wygląd

Wtyczka czyściła przy każdej publikacji cały cache razem ze zminifikowanymi plikami CSS. W oknie między skasowaniem a odbudowaniem strona linkowała do arkusza, którego nie było - i przez chwilę wyświetlała się jako goły HTML. Przy kilkunastu wpisach dziennie zdarzało się to regularnie.

Pro tip: po publikacji wpisu czyść punktowo - sam wpis, stronę główną, jego kategorie i kanał RSS. Nowy artykuł nie zmienia zawartości pliku CSS, więc nie ma powodu go kasować.

Lista kontrolna, jeśli chcesz to powtórzyć u siebie

  1. Zrób dziesięć pomiarów na niezmienionej stronie. Zapisz medianę i zakres. To jest Twój szum.
  2. Powtórz serię z zablokowanymi domenami zewnętrznymi. Różnica to sufit Twoich możliwości.
  3. Dopiero teraz zmieniaj po jednej rzeczy naraz i mierz serią, nie pojedynczym przebiegiem.
  4. Jeśli zakresy przed i po zachodzą na siebie - wycofaj zmianę. Brak dowodu to nie dowód.
  5. Zacznij od usuwania, nie od minifikacji. Plik, którego nie ma, jest zawsze najszybszy.
  6. Szukaj wymuszonych przeliczeń układu. Bywają warte 70 ms za jedną linijkę poprawki.
Google · Twoje źródłaPromptowy wyżej w Twoim Google - jednym kliknięciemDodaj do preferowanych źródeł

Skąd te liczby

Wszystkie wartości pochodzą z 121 pomiarów Lighthouse w dziewięciu seriach, wykonanych na tym serwisie w dniach 18-19 września 2026 na czterech typach stron: głównej, wpisie, recenzji i sklepie. Obie odrzucone hipotezy zostały wdrożone na produkcji, zmierzone i wycofane. To nie jest zestawienie cudzych porad - to jest sprawozdanie z tego, co u mnie zadziałało i co nie.

// Newsletter

Cały tydzień w AI, w jednym mailu

Wybrane premiery, narzędzia i analizy. Raz w tygodniu, prosto do skrzynki.

Zapisz się za darmo →
Za darmo. Wypisujesz się jednym kliknięciem.

Najczęstsze pytania

Ile razy uruchomić Lighthouse, żeby wynik był wiarygodny?

Minimum pięć przebiegów na jeden wariant, a zakresy przed i po zmianie nie mogą się na siebie nakładać. Autor wykonał 121 pomiarów w dziewięciu seriach i dopiero wtedy wyniki pozwoliły odrzucić błędne hipotezy.

Czy sklejanie plików CSS w jeden plik przyspiesza stronę?

Nie zawsze - w opisanym teście TBT wzrósł z 76 ms do 372 ms po połączeniu kilku arkuszy w jeden plik 69 KB. Przy HTTP/2 liczba żądań nie jest problemem, a jedno długie zadanie parsowania blokuje wątek główny bez możliwości przerwania.

Jak requestIdleCallback z limitem czasu 3000 ms wpłynął na TBT sklepu?

TBT wzrósł z 64 ms do 265 ms, bo limit czasu sprawił, że przeglądarka odpaliła wszystkie odroczone zapytania jedną serią dokładnie w oknie pomiaru TBT. Zamiast rozłożyć pracę w czasie, skrypt zebrał ją w jeden korek.

Co zrobić, gdy zewnętrzne skrypty reklamowe psują wyniki Core Web Vitals?

Przed optymalizacją własnego kodu należy zrobić serię pomiarów z zablokowanymi domenami stron trzecich - różnica to realny sufit możliwości. W opisanym przypadku zablokowanie stosu reklamowego zmniejszyło rozrzut FCP z 22% do 0,7% i ustabilizowało wynik na 77/77.

// czytaj też

Podobne tematy na Promptowym

Piotr Olszewski

Piotr Olszewski

ADMINISTRATOR

Piotr Olszewski - twórca i autor Promptowego, polskiego serwisu o sztucznej inteligencji. Codziennie śledzi premiery modeli, narzędzia i regulacje AI, i tłumaczy je prostym, konkretnym językiem.

// mapa strony

🛒 Sklep Kinetyka Google AI Gemini Pro 170 zł CapCut Pro 460 zł/rok n8n Cloud Starter 320 zł/rok Zobacz wszystko →
promptowy w liczbach 0tekstów w archiwum0newsów z ostatnich 7 dni0modeli wideo w obserwatorium0zagadek w grach
× powiększenie