Google używa Core Web Vitals jako jednego z czynników rankingowych od 2021 roku. W 2024 roku wymieniono FID na INP — bardziej wymagający wskaźnik. W 2025 nic się nie zmieni w samych wskaźnikach, ale Google podkreśla coraz mocniej że strony, które łapią się w „good” thresholds, dostają preferencyjne traktowanie. Ten artykuł to przewodnik po tym, co naprawić w pierwszej kolejności i czym mierzyć.
Trzy wskaźniki, które się liczą
Core Web Vitals to trzy metryki — każda mierzy inny aspekt user experience. Google publikuje progi „good” i „needs improvement”; jeśli jesteś poniżej „good” w 75% wizyt z ostatnich 28 dni, masz spadek pozycji w wyszukiwarce.
- LCP (Largest Contentful Paint) — kiedy pojawia się największy element widoczny na ekranie (zwykle hero image lub headline). Próg good: ≤2,5s.
- INP (Interaction to Next Paint) — jak szybko strona reaguje na klikinięcie/dotyk/keypress. Próg good: ≤200ms.
- CLS (Cumulative Layout Shift) — czy elementy strony nie skaczą podczas ładowania (np. obraz wczytuje się i rozpycha tekst). Próg good: ≤0,1.
Co naprawić w pierwszej kolejności
Z naszego doświadczenia ~70% problemów z Core Web Vitals to wina obrazów i fontów. Zacznij od tego — zwykle przeskakujesz z „needs improvement” na „good” w 1–2 godziny.
1. Obrazy
- Zawsze podawaj
widthiheightw<img>— to eliminuje CLS - Używaj WebP lub AVIF zamiast PNG/JPG (oszczędność 30–60%)
- Lazy loading:
loading="lazy"dla obrazów pod fold,fetchpriority="high"dla hero - Responsive images:
srcset+sizesżeby mobilki nie pobierały desktopowych rozmiarów - Format conversion automatycznie: Cloudflare Polish, Vercel Image Optimization, Next.js
<Image>
2. Fonty
font-display: swap— tekst pokazuje się natychmiast w fallback, potem swapuje na docelowy- Preload tylko tego fontu, który jest na początku (zwykle 1 weight bold lub semibold)
- Self-host fontów albo Google Fonts z
display=swap(już domyślny w generatorach) - Subset — jeśli używasz tylko polskiego, nie pobieraj wersji z japońskim i arabskim
3. JavaScript
JS jest najgorszym wrogiem INP. Każda biblioteka, każdy chunk webpacka to potencjalny czas blokowania interakcji. Najczęstsze winowajcy:
- Heavy frameworks ładowane synchronicznie (React, Vue) — używaj
deferlubasync - Third-party scripts (chat widgets, analytics, A/B testing) — ładuj po
loadlub przez Partytown - Animacje JS zamiast CSS —
transformiopacityw CSS są praktycznie darmowe
Jak mierzyć — lab vs field data
Lighthouse i PageSpeed Insights pokazują lab data — symulację z określonymi parametrami (np. 4G slow). To daje pojedynczą próbkę. Field data (Chrome User Experience Report — CrUX) to realne dane z użytkowników Chrome. Google używa CrUX do rankingu, nie Lighthouse.
Konsekwencja: możesz mieć Lighthouse 95/100, a CrUX „needs improvement”, bo Twoi prawdziwi userzy mają wolniejsze połączenia niż test. Patrz na CrUX w Search Console → Core Web Vitals.
Narzędzia, które warto znać
- Google Search Console — Core Web Vitals report z CrUX (real users), 28-dniowe okno
- PageSpeed Insights — Lighthouse + CrUX w jednym, dla pojedynczego URL
- Lighthouse CI — automatyzacja testów w pipeline build (np. GitHub Actions)
- Web Vitals Chrome Extension — pomiar real-time podczas klikania po stronie
- WebPageTest — bardziej szczegółowy niż Lighthouse, możesz testować z różnych lokalizacji
Najczęstsze błędy
- Optymalizujesz tylko Lighthouse, ignorując CrUX — Google patrzy na realnych userów
- Pomijasz mobile bo desktop ma 100/100 — 60%+ ruchu to mobile, mierz tam
- Ładujesz analytics blocking — GA4, Meta Pixel, Hotjar potrafią dodać 500ms TBT
- Animacje GSAP/Framer Motion w hero — często kosztują 200–400ms TBT na mobile
- Cookie banner ładuje się sync — odłóż na po
DOMContentLoaded