Pagespeed 100/100 w Next.js — case study optymalizacji strony usługowej
Jak osiągnąć wynik 100/100 w PageSpeed Insights dla strony Next.js? Case study optymalizacji LCP, INP i CLS — fonty, obrazy, JavaScript, third-party scripts i Server Components.
Mamy tu typową stronę usługową zbudowaną w Next.js, wyposażoną w Google Analytics, Google Tag Manager, prosty formularz kontaktowy, galerię zdjęć i animacje – czyli standardowy zestaw. Na początku testy PageSpeed Insights pokazały wyniki: 67/100 na urządzeniach mobilnych i 89/100 na komputerach stacjonarnych.
Lighthouse wskazało główne problemy: duże zasoby JavaScript (GTM) blokujące renderowanie, niezoptymalizowane obrazy, brak odpowiednich wskazówek dla przeglądarki (resource hints) oraz nadmierne przesunięcia układu strony (layout shift) związane z ładowaniem czcionek.
Naszym celem było poprawienie rzeczywistych wskaźników Core Web Vitals, a przy okazji osiągnięcie jak najwyższego wyniku w testach laboratoryjnych Lighthouse. Wynik 100/100 zarówno na urządzeniach mobilnych, jak i desktopowych jest możliwy do uzyskania, ale nie powinien być celem za wszelką cenę. Generalnie uzyskanie powyżej 90/100 w zupełności wystarcza.
Krok 1: Fonty — eliminacja layout shift
Problem stanowiły Google Fonts ładowane z CDN powodowały FOUT i CLS.
Rozwiązaniem było użycie next/font z self-hostingiem i size-adjust:
Code
import { Inter } from 'next/font/google'const inter = Inter({ subsets: ['latin', 'latin-ext'], display: 'swap', variable: '--font-inter',})
W wyniku tych działań wyeliminowaliśmy zewnętrzny requestu do fonts.googleapis.com i uzyskaliśmy spadek CLS z fontów z 0.12 do 0.00,
Krok 2: Obrazy — next/image z priority i sizes
Problem stanowił obraz hero image (LCP element) ładował się z opóźnieniem, brak sizes powodował pobieranie zbyt dużych wariantów.
Code
<Image src={heroImage} alt="Strona internetowa Next.js" priority // Najwyższy priorytet dla LCP image placeholder="blur" sizes="100vw" className="h-auto w-full"/>
Rozwiązaniem jest konwersja wszystkich obrazów na WebP/AVIF automatycznie przez next/image, dodanie sizes do każdego <Image> z precyzyjnymi breakpointami.
W wyniku tych działań LCP spadł z 3.2 s do 1.4 s.
Krok 3: Third-party scripts — lazy loading GTM
Problemem okazał się Google Tag Manager (130 KB), który blokował rendering. GTM ładowany w <head> opóźniał FCP o 800 ms.
Rozwiązanie: @next/third-parties z opóźnionym ładowaniem:
Zauważyliśmy, że w projekcie było zbyt wiele Client Components. Przykładowo, sekcja hero, nawigacja i stopka były oznaczone jako 'use client', choć w rzeczywistości nie wymagały interaktywności po stronie klienta.
Rozwiązaniem było przekształcenie tych elementów na Server Components wszędzie tam, gdzie było to możliwe. Client Components zostały zachowane wyłącznie dla funkcjonalności wymagających faktycznej interakcji, takich jak przełącznik menu mobilnego, formularz kontaktowy czy animacje związane ze scrollowaniem.
Code
/* PRZED — cały hero jako Client Component'use client'; // ← niepotrzebneexport function HeroSection() { ... } *//* PO — Server Component (zero JS w bundle) */export function HeroSection() { ... }
W wyniku tych optymalizacji JavaScript bundle zmalał z 210 KB do 85 KB (gzipped).
Krok 5: Preconnect i DNS prefetch
Metadata API nie służy do dowolnego generowania tagów preconnect i dns-prefetch, więc najprościej dodać je bezpośrednio w <head>:
Podsumowując wszystkie działania optymalizacyjne dobiliśmy do poniższych wyników:
Metryka
Przed
Po
PageSpeed Mobile
67
100
PageSpeed Desktop
89
100
LCP
3.2 s
1.1 s
INP
180 ms
45 ms
CLS
0.12
0.00
TBT
420 ms
60 ms
JS bundle
210 KB
85 KB
CSS
45 KB
12 KB
Checklist optymalizacji
Przed każdym deploymentem, warto skorzystać z tej krótkiej checklisty:
next/font dla wszystkich fontów (z latin-ext dla polskiego),
next/image z priority na LCP element i sizes na każdym obrazie,
Third-party scripts z strategy="lazyOnload" lub @next/third-parties,
Minimum Client Components — Server Components jako domyślne,
Preconnect do zewnętrznych domen,
Tailwind z poprawnymi content ścieżkami,
Animacje CSS zamiast JS dla micro-interactions,
headers() w next.config.ts z cache-control dla statycznych assets.
Podsumowanie
100/100 w PageSpeed da się osiągnąć w warunkach laboratoryjnych, ale większe znaczenie mają stabilnie dobre Core Web Vitals na produkcji. Największe zyski w Next.js dają: self-hosted fonty (CLS → 0), atrybut priority na LCP image, lazy loading third-party scripts i minimalizacja Client Components.
Nie musisz rezygnować z funkcjonalności, ale musisz ładować je w sposób logiczny i przemyślany.
Najczęściej zadawane pytania
Czy 100/100 naprawdę wpływa na pozycję w Google?
Pośrednio lub w ograniczony sposób. Google bierze pod uwagę page experience, ale nie warto gonić za samym 100/100 kosztem wartości dodanej produktu. Najważniejsze jest utrzymanie dobrych Core Web Vitals i szybkiej, stabilnej strony dla użytkownika, ale nie popadajmy w myślenie, że 100/100 jest celem samym w sobie.
Czy to jednorazowa optymalizacja?
Nie, ponieważ każda nowa biblioteka, obraz czy skrypt third-party może obniżyć wynik. Monitoruj PageSpeed regularnie, a najlepiej w CI/CD pipeline.
Czy wynik 100 na localhost = 100 na produkcji?
Nie koniecznie, ponieważ Lighthouse lokalnie nie mierzy TTFB serwera, opóźnień CDN ani real-user conditions. Zawsze testuj na produkcyjnym URL.
Pracuję z tym zawodowo.
Jeśli chcesz połączyć SEO, analitykę, Google Ads i warstwę techniczną strony w jeden sensowny system wzrostu, skontaktuj się ze mną. Pomagam układać wdrożenia, które nie kończą się na samym tagowaniu, ale wspierają widoczność, pomiar i konwersję.
Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.
Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.
Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?
Fachowe porównanie Astro.js i Next.js z perspektywy developera pracującego na co dzień w Next.js. Architektura, wydajność, SEO, DX, koszty i konkretne use case — z benchmarkami i przykładami kodu.
WordPress → Next.js — migracja treści, redirecty 301 i zachowanie pozycji SEO
Jak przenieść stronę z WordPress na Next.js bez utraty pozycji w Google? Eksport treści, mapowanie URL, redirecty 301, migracja obrazów i weryfikacja indeksacji.
Google Search Console + Next.js — indeksacja, błędy, performance i co z nimi robić
Jak korzystać z Google Search Console dla strony Next.js? Weryfikacja, sitemap, indeksacja, Core Web Vitals, crawl budget i najczęstsze problemy — praktyczny poradnik.