Ana Sayfa / Blog / JavaScript bundle splitting: dynamic import ne zaman değer?

JavaScript bundle splitting: dynamic import ne zaman değer?

Bundle'ı parçalara ayırmak herkesin önerdiği bir pratik, ama her durumda değer katmıyor. Gerçek ölçümlerle ne zaman değerli olduğunu paylaştım.

Bir SPA projemde webpack-bundle-analyzer görüntüsünü açtığımda gördüm, ana bundle 2.8 MB’tı. “Code splitting yapalım” denildi, tüm route’lara lazy loading ekledik. Bundle boyutu 2.8 MB’tan 480 KB + 12 chunk’a düştü. İlk yükleme 4 saniye hızlandı. Hikaye güzel gibi. Ama sonraki projede aynı yaklaşım hiç fayda getirmedi, hatta yavaşlattı. Fark neydi, onu anlatayım.

Code splitting ne yapıyor?

Webpack, Rollup, Vite gibi bundler’ların import() syntax’ı gördüğünde o modülü ayrı bir chunk’a ayırması. İlk yüklemede sadece kritik kod iniyor, diğer parçalar lazım olunca indiriliyor.

Ne zaman değer?

  1. Route-based splitting. SPA’da her sayfa ayrı chunk. Kullanıcı /dashboard’da ise /admin chunk’ı indirilmez. Çok sayıda sayfa varsa belirgin kazanım.
  2. Büyük üçüncü taraf kütüphaneler. Chart.js, PDF.js, rich text editor, syntax highlighter. Her kullanıcı görmüyor. Gerektiğinde lazy.
  3. Modal veya overlay içeriği. Kullanıcı nadiren açıyor, asıl flow’da ihtiyaç yok.
  4. A/B test variant’ları. Tüm variant’lar bir arada gelirse paket şişiyor, lazy load ile sadece kullanıcının variant’ı iniyor.

Ne zaman değer katmaz?

  1. Küçük bundle. Toplam paket zaten 100 KB altındaysa chunk’lara bölmek fazladan request yaratır. HTTP overhead bundle avantajını yiyor.
  2. Tek sayfalık uygulama. Landing page’de tüm kod zaten ilk sayfa için gerekli. Bölmenin anlamı yok.
  3. Kritik path’te splitting. Homepage’i üç chunk’a böldüyseniz ve üçü de ilk load’da lazım oluyorsa, tek büyük dosyaya göre daha yavaş. İki extra HTTP round-trip.
  4. Chunk’lar arası bağımlılık çok. A chunk B’yi, B chunk C’yi istiyorsa bir waterfall oluşuyor. Single bundle’dan yavaş.

İkinci projede neler yanlış gitti

Site bir dashboard panel, 8 sayfadan oluşuyordu. İlk yükleme bundle’ı 520 KB, gzipped 180 KB. Splitting uyguladık, main chunk 95 KB, her sayfa chunk 40-80 KB.

Rakamlar iyi görünüyordu ama LCP bozuldu. Sebep, her sayfa geçişinde yeni chunk indirilmesi gerekti, kullanıcı algılanabilir gecikme yaşadı. Tek bundle’da 180 KB indirip bitince tüm geçişler anındaydı. Splitting sonrası her sayfa 50ms takılma ekledi.

Çözüm prefetch oldu. Webpack’in magic comment’leriyle bir sonraki muhtemel chunk’ı idle’da indirdik:

const Dashboard = lazy(() => import(/* webpackPrefetch: true */ './Dashboard'));

Bu prefetch sayesinde main bundle yüklendikten sonra idle zamanda chunk’lar iniyor. Kullanıcı rotaya gelince cache’te oluyor.

Ölçme yöntemi

Sadece bundle size bakmayın. Gerçek metrikler:

  • FCP (First Contentful Paint): ilk içeriği ne zaman görüyor?
  • LCP (Largest Contentful Paint): ana içerik ne zaman tamamlanıyor?
  • TTI (Time to Interactive): ne zaman etkileşime hazır?
  • Route transition time: sayfadan sayfaya geçiş süresi.

Splitting FCP ve LCP’yi iyileştirir genelde, ama route transition’ı kötüleştirebilir. Trade-off tablosunu kendi siteniz için kurun.

Chunk sayısı kontrolü

Çok küçük chunk’lar kötü. Webpack’in splitChunks optimizasyonunda minSize: 30000 (30 KB) gibi eşik var. 5 KB’lık chunk yaratmanın anlamı yok, HTTP overhead chunk içeriğini aşar.

Lodash, moment gibi paketleri granular import edin. Tek fonksiyon kullanıyorsanız tüm paketi çekmeyin:

// kötü
import _ from 'lodash';

// iyi
import debounce from 'lodash/debounce';

Daha iyisi, moment yerine date-fns (tree-shakable), lodash yerine lodash-es (tree-shakable) kullanın.

Vite vs Webpack

Vite dev mode’da splitting zaten doğal çünkü ESM. Prod’da Rollup kullanır, onun da splitting desteği var ama ayarları farklı.

Webpack’te chunk stratejisi kontrol etmek lazım:

splitChunks: {
  chunks: 'all',
  cacheGroups: {
    vendor: { test: /[\/]node_modules[\/]/, name: 'vendors' },
    common: { minChunks: 2, name: 'common' }
  }
}

vendor chunk’ı ayrılır, bu genelde iyi çünkü app kodundan daha az değişiyor, uzun cache alabiliyor.

Sonuç

Code splitting araç, çözüm değil. Ölçün, gerçekten fayda veren yerde uygulayın. Ufak projede zaman kaybetmeyin. Büyük projede splitting + prefetch kombinasyonu ile hem kullanıcı hem metrikler mutlu.

Bu konuda bir projeniz mi var?

Kısa bir özet bırakın, 24 saat içinde size dönüş yapayım.

İletişime Geç