"Next.js je spor" rečenica je koju čujem gotovo uvijek kad netko dođe s problemom performansi — i gotovo nikad nije istinita u tom obliku. Framework sam po sebi, kad se koristi kako je zamišljen, spada u brže opcije na tržištu. Kad je aplikacija spora, uzrok je gotovo uvijek jedan (ili nekoliko) od šest čestih obrazaca ispod. Evo kako ih dijagnosticirati i popraviti, redom po tome koliko se često javljaju u praksi.
1. Sve je client komponenta
Najčešći uzrok sporog Next.js projekta uopće nije Next.js problem — nego navika iz starog React SPA svijeta. "use client" na vrhu layouta, koji se onda vuče na svaku podređenu komponentu, gasi prednost server komponenti (renderiranje na serveru, manji JavaScript bundle prema klijentu) za cijelu aplikaciju.
Dijagnoza: otvorite Network tab i pogledajte koliko JavaScripta preglednik mora preuzeti i izvršiti prije prvog interaktivnog stanja.
Popravak: "use client" stavljajte što niže u stablu — samo na komponentu koja stvarno treba interaktivnost (onClick, useState). Sve oko nje neka ostane server komponenta.
2. Slike bez optimizacije
Ručno ubačen <img> tag s neoptimiziranom slikom od 4 MB zna sam pojesti više vremena učitavanja od cijelog ostatka stranice zajedno.
Dijagnoza: Lighthouse izvještaj gotovo uvijek prvo prijavi upravo ovo — "properly size images" i "serve images in next-gen formats".
Popravak: koristite ugrađenu next/image komponentu — automatski generira responzivne veličine, konvertira u WebP/AVIF i lijeno učitava slike izvan vidljivog okvira. Ručno rukovanje slikama u Next.js projektu gotovo je uvijek korak unatrag.
3. Sve se dohvaća server-side na svaki zahtjev
Podaci koji se mijenjaju rijetko (cjenik, blog, dokumentacija) često se ipak dohvaćaju iznova na svaki zahtjev, umjesto da se generiraju jednom i posluže statički.
Dijagnoza: provjerite vrijeme odgovora servera (Time to First Byte) za stranice čiji se sadržaj rijetko mijenja — ako je visoko, vjerojatno se sadržaj generira uzalud, iznova.
Popravak: koristite statičku generaciju ili ISR (Incremental Static Regeneration) s razumnim revalidate intervalom za sadržaj koji se ne mijenja iz sekunde u sekundu. Dinamičko renderiranje rezervirajte za stvarno personalizirane ili trenutne podatke.
4. Vodopad zahtjeva (request waterfall)
Komponenta A čeka podatak, tek onda renderira komponentu B koja čeka svoj podatak, koja tek onda renderira C — svaki dodatni korak dodaje puno vrijeme umjesto da se izvršavaju paralelno.
Dijagnoza: u Network tabu vidite zahtjeve koji se ulančano izvršavaju jedan za drugim, umjesto istovremeno.
Popravak: dohvaćajte podatke što više paralelno (Promise.all), a ne ugniježđeno čekanje. U App Routeru, razdvajanje neovisnih dijelova stranice u zasebne server komponente s vlastitim dohvatom podataka često rješava problem samo po sebi.
5. Prevelik JavaScript bundle
Uvezena cijela biblioteka za jednu funkciju (npr. cijeli moment.js za formatiranje jednog datuma) tiho napuhava bundle koji preglednik mora preuzeti i izvršiti prije nego što stranica postane interaktivna.
Dijagnoza: next build ispisuje veličinu svake rute — pratite koje su neočekivano velike, i pokrenite bundle analyzer da vidite što ih čini takvima.
Popravak: birajte manje biblioteke ili uvozite samo dio koji trebate, koristite dinamički import (next/dynamic) za teške komponente koje nisu odmah potrebne (modali, editori, grafovi ispod skrolla).
6. Baza podataka bez indeksa ili s N+1 upitima
Kad je frontend optimiziran, a stranica je i dalje spora, uzrok često nije u Next.js sloju uopće — nego u upitu prema bazi koji se izvršava jednom po svakoj stavci liste umjesto jednom za cijelu listu.
Dijagnoza: logirajte trajanje upita prema bazi po zahtjevu; N+1 obrazac prepoznat ćete po desetinama gotovo identičnih upita za jednu stranicu.
Popravak: dohvaćajte povezane podatke jednim upitom s JOIN-om ili include, ne u petlji. Dodajte indekse na stupce po kojima često filtrirate ili sortirate.
Redoslijed kojim vrijedi krenuti
- Pokrenite Lighthouse i
next build— dobijete grubu sliku bez ijedne linije novog koda. - Provjerite Network tab za vodopade i prevelike resurse.
- Tek onda idite u profiliranje pojedinih komponenti — to je najsporiji korak i vrijedi ga ostaviti za kraj, kad ste veće probleme već riješili.
Zaključak
Rijetko je "Next.js spor" — gotovo uvijek je "ova specifična aplikacija spora zbog jednog od ovih šest obrazaca", a razlika je bitna jer druga formulacija ima rješenje. Prođite popis odozgo prema dolje na svom projektu; iskustvo pokazuje da većina aplikacija ima barem tri od šest grešaka istovremeno, i da rješavanje prve dvije-tri donosi najveći skok u brzini uz najmanje uloženog truda.




