Code splitting i lazy loading smanjuju JavaScript, CSS i medije koje posjetilac mora preuzeti prije nego što stranica postane upotrebljiva. Prodavnica, dashboard ili marketing sajt mogu slati jedan ogroman bundle koji se parsira pri svakoj posjeti, ili mali prvi prikaz, a grafikon, mapu, editor i slike van ekrana učitati tek kada nekome zaista zatrebaju.
Sadržaj
U CodeWizu pregledamo šta browser preuzima, dijelimo bundle po rutama i po funkcijama, odgađamo medije i tuđe skripte i u CI stavljamo budžet veličine, tako da sljedeća funkcija ne pojede dobitak u tišini. Rad pokriva Vite, webpack, Rollup, Next.js, Nuxt, obične PHP šablone i WordPress, uključujući prodavnice u kojima nekoliko plugina učitava skripte na svakom URL-u.
Usluga je za timove kojima Lighthouse ocjena padne svaki put kada se doda widget, za prodavnice čiji mobilni posjetioci odustanu tokom dugog bijelog ekrana i za proizvode koji kasne na klik iako server odgovara brzo. Kada su code splitting i lazy loading vezani za budžet i za podatke sa stvarnih uređaja, stranica ostaje brza kako proizvod raste.

Optimizacija bundlea: manje JavaScripta u prvom prikazu
Optimizacija bundlea znači pronaći šta je završilo u JavaScript fajlu i ukloniti, zamijeniti ili odgoditi sve što prvom prikazu ne treba. Bundler kao što su Vite, Rollup ili webpack prođe graf importa i izbaci jedan ili više fajlova. Tree-shaking odbacuje nekorištene exporte kada je kod pravi ESM i kada je oznaka sideEffects iskrena. Ne spašava vas od root importa paketa ikona, biblioteke za datume ili UI kita koji sve re-eksportuje iz jednog barrel fajla.
Šta težak bundle košta poslovanje
Vrijeme preuzimanja je tek prvi trošak. Browser taj JavaScript još mora parsirati i kompajlirati na main threadu, a na telefonu srednje klase taj posao odgađa prvi prikaz i prvi klik. Google u Core Web Vitalsu Largest Contentful Paint iznad 2.5 sekunde i Interaction to Next Paint iznad 200 milisekundi tretira kao loš rezultat. Oba se pogoršavaju kada stranica pri startu vuče stotine kilobajta koda koji se ne koristi.
Kako optimizujemo bundle
- Vizuelna mapa bundlea uz
rollup-plugin-visualizer, webpack-bundle-analyzer ili Next.js analizator, tako da su najteži moduli vidljivi prije nego što iko prepisuje komponentu. - Direktni importi umjesto barrel fajlova, i zamjena biblioteka manjima gdje API to dozvoljava: pomoćnik za datume veličine jednog jezika umjesto biblioteke za sve namjene, pojedinačne ikone umjesto cijelog seta.
- Browserslist koji odgovara browserima koje zaista podržavate, tako da moderni posjetioci ne preuzimaju polyfille za engine koje više ne servirate.
- Chunk po ruti za svaki važniji ekran, plus zajednički vendor chunk koji se mijenja samo kada se mijenjaju zavisnosti, pa se povratnicima čuva dugotrajni keš.
- Provjera u CI-ju alatima size-limit, bundlesize ili Lighthouse budžetom. Pull request koji početni JavaScript gurne preko dogovorenog limita pada prije mergea.
| Pristup | Šta se dijeli | Kada se učitava | Na šta paziti |
|---|---|---|---|
| Chunkovi ruta | Svaka stranica ili layout | Pri navigaciji | Prazan razmak ako sljedeći prikaz nema placeholder |
| Import komponente | Težak widget | Na klik, u idle vremenu ili kada postane vidljiv | Kašnjenje pri prvoj upotrebi tog widgeta |
| Vendor chunk | Zajedničke biblioteke | Sa prvom stranicom kojoj trebaju | Jedna izmjena zavisnosti može poništiti veliki keširani fajl |
| Podjela CSS-a | Stilovi jedne rute | Zajedno sa tom rutom | Bljesak nestilizovanog sadržaja ako nema kritičnog CSS-a |
| Odgođene tuđe skripte | Chat, tagovi, video playeri | Nakon pristanka ili interakcije | Zadržite tagove koje poslovanje zaista mjeri |
Operator dinamičkog import() je jezička mogućnost iza većine ovih podjela. Bundler svaki import pretvara u zaseban fajl; mi odlučujemo koji importi pripadaju prvom ekranu.
Lazy loading slika, videa i sadržaja van ekrana
Lazy loading odgađa posao koji posjetilac još ne vidi. Na hero slici pogoršava Largest Contentful Paint. Na svemu ispod prvog ekrana, na embedovima i na skriptama koje čekaju klik, to je jedno od najjeftinijih ubrzanja postojećeg sajta.
Slike, video i embedovi
- LCP slika ide odmah: navedene širina i visina, moderan format kao AVIF ili WebP, responzivni
srcsetifetchpriority="high", da je browser povuče prvu. - Slike ispod prvog ekrana koriste
loading="lazy"idecoding="async", sa dimenzijama da se layout ne pomjeri kada stignu. - Video koristi
preload="none"i poster sliku. Fajl od više megabajta ne počinje preuzimanje na stranici koju posjetilac možda nikad ne pusti. - YouTube, mape i drugi iframeovi ostaju statički poster do klika, a pravi iframe se montira tek tada.
loading="lazy"pokriva embedove koji moraju biti prisutni ranije. - Dugi članci mogu koristiti
content-visibility: autona sekcijama daleko dole, pa browser preskače layout dok čitalac ne stigne.
<img src="hero.avif" alt="Product on a table" width="1600" height="900" fetchpriority="high">
<img src="gallery.avif" alt="Detail of the same product" width="800" height="600" loading="lazy" decoding="async">Widgeti i tuđe skripte
Chat widgeti, tagovi za A/B testove, help desk i društveni embedovi često pojedu više vremena na main threadu nego sama stranica. Učitavamo ih nakon prve interakcije, nakon pristanka ili kada im se kontejner približi viewportu. Na WordPressu i WooCommerceu isto važi za plugine: skripte i stilovi idu samo na šablone koji ih koriste, a korpa, checkout i nalog zadržavaju asete koji im zaista trebaju. CDN i sloj keša i dalje su važni za HTML i slike oko tog JavaScripta — isto edge podešavanje koje opisujemo u vodiču o profesionalnoj Cloudflare konfiguraciji.

Dinamički importi: kod stiže u trenutku korištenja
Dinamički import je poziv funkcije koji vraća promise i govori bundleru da izbaci zaseban chunk. Editor, mapa, traka za bogati tekst, admin grafikon i fajl jezika koji posjetilac nije izabrao ostaju van početnog preuzimanja. Prvi put kada zatrebaju, browser povuče taj jedan fajl.
document.querySelector('#open-chart').addEventListener('click', async () => {
const { renderChart } = await import('./chart.js');
renderChart(document.querySelector('#chart'), window.reportData);
});- React:
lazy()iSuspenseoko komponente koja ima default export, uz fallback koji rezerviše prostor da stranica ne poskoči. - Vue i Nuxt:
defineAsyncComponent, ili Nuxtovi prefiksi za lazy komponente, za panele koji se otvaraju po potrebi. - Next.js: segmenti ruta već dijele App Router.
next/dynamicpokriva widgete samo za klijent, poput mapa koje ne treba da rade tokom renderovanja na serveru. - Vite i webpack: dovoljan je običan
import().manualChunksdrži React, Vue ili drugi stabilan runtime u vlastitom keširanom fajlu. Prefetch ide na jednu ili dvije rute koje će posjetilac vjerovatno otvoriti sljedeće, a ne na svaki chunk.
Imenujemo fallback, stanje greške i timeout. Chunk koji padne na nestabilnoj mobilnoj mreži treba ponuditi ponovni pokušaj, a skeleton učitavanja treba odgovarati visini widgeta.
Praćenje performansi za code splitting i lazy loading
Podjela koju niko ne mjeri vremenom se raspe. Nove zavisnosti, novi plugin i novi marketing tag dodaju težinu, a nazadovanje se u podacima sa stvarnih uređaja vidi tek sedmicama kasnije. Praćenje performansi zatvara taj krug: laboratorijska provjera na svakoj izmjeni i podaci sa stvarnih uređaja.
| Signal | Cilj koji pratimo | Odakle dolazi |
|---|---|---|
| JavaScript pri prvom učitavanju | Ispod dogovorenog budžeta u kilobajtima | Analizator bundlea i provjera veličine u CI-ju |
| Largest Contentful Paint | Ispod 2.5 sekunde u stvarnom saobraćaju | web-vitals, CrUX, Lighthouse |
| Interaction to Next Paint | Ispod 200 milisekundi | web-vitals i performance trace |
| Dugi zadaci na main threadu | Manje zadataka preko 50 milisekundi pri startu | Chrome performance panel |
| Keširanje chunkova | Stabilan hash za kod koji se nije mijenjao | CDN logovi i Cloudflare analitika |
- Lighthouse CI radi na pull requestovima uz mobilni profil, pa je teža stranica vidljiva prije objave.
- Biblioteka
web-vitalsšalje LCP, INP i CLS iz stvarnih sesija u analitički alat koji već koristite. - Podaci Chrome UX Reporta, kada domen ima dovoljno prometa, pokažu da li je laboratorijski dobitak preživio stvarne telefone i mreže.
- Source mape idu u praćenje grešaka, a ne u javnost kao dodatna težina preuzimanja.
- Kratka bilješka u repozitoriju pamti budžet i koje rute smiju biti teže, na primjer editor za prijavljenog korisnika.
Laboratorijske ocjene i podaci sa stvarnih uređaja odgovaraju na različita pitanja, i držimo oboje. Ista navika mjerenja vodi nas i ka rezultatu 100/100 za performanse stranice, uz keš ispred HTML-a kada stack to traži — uključujući Varnish ispred dinamičkog sajta. Googleova dokumentacija za Core Web Vitals je referenca za pragove iznad.
Podjela po rutama, zajednički chunkovi i granica koristi
Više chunkova samo po sebi ne znači brži sajt. Svaki fajl je zahtjev, a vodopad sitnih chunkova može pojesti vrijeme koje ste uštedjeli smanjenjem prvog. HTTP/2 i HTTP/3 čine mnogo malih fajlova jeftinijim nego na HTTP/1.1; i dalje nisu besplatni. Kod grupišemo onako kako se posjetioci zaista kreću kroz proizvod.
- Jedan chunk po ruti ili layoutu, a ne jedan chunk po dugmetu.
- Biblioteke koje koristi skoro svaka stranica žive u zajedničkom chunku sa stabilnim hashom.
- Kod jednog admin ekrana učitava se samo unutar tog ekrana.
- Kritični CSS prvog prikaza je ubačen u stranicu ili učitan odmah; ostatak može pratiti rutu.
- Prefetch ide na hover ili u idle za sljedeću vjerovatnu stranicu, i to tek kada je trenutna stranica mirna.
Stranice renderovane na serveru i statičke stranice prate isto pravilo. HTML prvog ekrana treba već sadržavati sadržaj, a kasniji JavaScript treba da ga nadogradi.
Code splitting i lazy loading: česte greške
- Lazy loading hero slike, što odgađa Largest Contentful Paint baš na elementu koji Google mjeri.
- Import cijele biblioteke ikona ili komponenti iz korijena paketa, što poništava tree-shaking.
- Poziv
import()na svakoj maloj komponenti, pa čekanje na lanac zahtjeva već pri startu. - Slanje polyfilla i legacy bundleova modernim browserima jer je browserslist ostao na podrazumijevanoj vrijednosti.
- Zaboravljen fallback fiksne visine, pa sadržaj poskoči kada stignu lazy slika ili chunk, a Cumulative Layout Shift strada.
- Zeleni Lighthouse na desktopu uzet kao dokaz, dok podaci sa mobilnih uređaja i dalje pokazuju sporu interakciju.
- WordPress plugini koji ispisuju skripte u footeru svakog šablona, uključujući stranice koje tu funkciju nikad ne koriste.
Od čega zavisi cijena rada na bundleu i učitavanju
Procjenu dajemo nakon što pogledamo produkcijski build, a ne odoka. Cijena prati oblik frontenda:
- Jedna Vite ili Next.js aplikacija sa jasnom mapom ruta manji je posao od sajta složenog od nekoliko plugina i page buildera.
- Broj šablona koji svaki učitava svoje skripte, posebno na WordPressu, WooCommerceu i sličnim stackovima.
- Koliko tuđih tagova marketing mora zadržati, i koji od njih mogu čekati pristanak ili klik.
- Da li su izmjene dizajna u opsegu, ili je rad ograničen na ponašanje učitavanja i izlaz builda.
- Praćenje: jednokratni audit, ili budžet koji ostaje u CI-ju i izvještaj sa stvarnih uređaja koji ostaje uključen.

Kako radimo
- Upoznavanje: mjerimo trenutni build, šablone i vitals sa stvarnih uređaja, i izlistamo module i tagove koji dominiraju prvim učitavanjem.
- Plan: dogovaramo budžet za početni JavaScript, koje rute se dijele, koje slike ostaju hitne i koje tuđe skripte čekaju.
- Izrada: mijenjamo importe, dodajemo dinamičke podjele, popravljamo markup slika i budžet bundlea vežemo za CI.
- Testiranje: uporedimo prije i poslije na mobilnom profilu i na stvarnom telefonu, uključujući sporu mrežu i chunk koji ne stigne.
- Puštanje: objavljujemo iza postojećeg sloja keša, pratimo LCP i INP sa stvarnih uređaja i držimo brzi rollback builda.
- Podrška: budžet ostaje na mjestu kako stižu nove funkcije, a chunkove preispitujemo kada ažuriranje zavisnosti pomjeri brojeve.
Zašto CodeWiz
- Full-stack rad na performansama: podjela bundlea, markup slika, Varnish i Cloudflare su kod istog tima koji gradi aplikaciju.
- Open-source alati: Vite, Rollup, webpack, Lighthouse i web-vitals, bez vlasničkog paketa za performanse.
- Savjet prema stacku: WordPress prodavnica i Next.js proizvod dobijaju različite podjele, jer su im uska grla različita.
- Tehnologija u službi poslovanja: sječemo bajtove koji odgađaju kupovinu ili prijavu, a bezazlen kod ostavljamo na miru.
- Fer cijene: vrhunski razvoj bez vrhunskih cijena, iz Banje Luke, uz rad na daljinu sa klijentima iz regiona i svijeta. Više o CodeWizu.
Često postavljana pitanja
Da li code splitting poboljšava Core Web Vitals?
Poboljšava vitals na koje JavaScript i slike zaista utiču. Manje skripti u prvom prikazu obično pomaže LCP-u i INP-u, a tačne dimenzije slika čuvaju CLS. Dobitak se vidi kada je uklonjeni kod bio na kritičnoj putanji. Mjerimo prije i poslije, umjesto da obećavamo konkretnu ocjenu.
Koja je razlika između code splittinga i lazy loadinga?
Code splitting razbija build na manje fajlove. Lazy loading odlučuje kada se ti fajlovi, i kada slike ili embedovi, traže. Bundle se može podijeliti, a svi chunkovi i dalje preuzeti odmah. Korisna kombinacija je mali početni fajl i jasno pravilo za sve ostalo.
Da li lazy loading šteti SEO-u?
Lazy loading slika ispod prvog ekrana je uobičajen i očekivan. Problem nastaje kada se glavni sadržaj sakrije iza JavaScripta na koji pretraživač ili korisnik moraju čekati, ili kada se odgodi slika koja čini najveći paint. Prvi ekran ostaje u HTML-u, a lazy loading ide na ono što dolazi poslije.
Može li se ovo uraditi na postojećem WordPressu ili React sajtu?
Može. React, Vue, Next.js i Nuxt projekti obično traže izmjenu importa i budžet u CI-ju. WordPress i WooCommerce projekti obično traže pregled skripti po šablonu, popravku markupa slika i odgodu tuđih tagova. Prepisivanje je rijetko potrebno.
Koliko traje optimizacija bundlea?
Fokusiran prolaz kroz jednu aplikaciju — analizator, najveći krivci, lazy loading slika i budžet u CI-ju — često je kratak angažman. Veliki WordPress sajt sa više tema ili migracija design sistema sa mnogo ruta traje duže, uglavnom jer svaki šablon treba provjeriti. Procjenu dobijate nakon što vidimo produkcijski build.
Koji bundler preporučujete?
Za nove frontende aplikacija obično koristimo Vite. Postojeći webpack, Next.js ili Nuxt buildovi ostaju na svom alatu, osim kada je sam build problem. Pravila podjele važnija su od imena bundlera, i to ćemo reći kada bi migracija koštala više nego što vraća.
Spremni za manji prvi load?
Pošaljite nam produkcijski URL ili build, i pokazaćemo šta prvi prikaz preuzima i koje podjele vrijedi uraditi. Kontaktirajte nas da razgovaramo o projektu, ili pogledajte naše usluge za code splitting i lazy loading.