Bundle Analizi Nasıl Yapılır? Hangi Paket Şişiriyor?
Proje bir süre sonra ağırlaşır; ama hangi bağımlılığın gerçekten sorun çıkardığı çoğu ekipte net görünmez. Build büyür, ilk yük yavaşlar, ayrıştırma süresi uzar. Sonra herkes genel laflara döner: paket çok büyümüş, biraz temizlemek lazım. Bundle analizi tam bu belirsizliği dağıtmak için yapılır. Amaç grafik seyretmek değil, hangi kodun neden ilk pakete girdiğini anlamaktır.
Proje bir süre sonra ağırlaşır; ancak hangi bağımlılığın gerçekten bant genişliğini ve işlem gücünü tükettiği çoğu ekipte net görünmez. Build çıktısı büyür, ilk yük yavaşlar, tarayıcının JavaScript'i ayrıştırma süresi uzar. Geliştiriciler genellikle "paket çok büyümüş" gibi yüzeysel çıkarımlara döner. Bundle analizi tam bu kör noktayı aydınlatmak için yapılır. Amaç grafiklerde gezinmek değil, hangi kod bloğunun neden ilk pakete (main chunk) dahil olduğunu netleştirmektir.
Bu tür analizler genelde kriz anlarında başlar. Lighthouse raporları JavaScript yükünün kırmızı bölgeye girdiğini işaret ettiğinde, ekip hangi paketin şiştiğini aramaya koyulur. Oysa sorun tek bir büyük commit ile oluşmaz. Dikkatsizce projeye eklenen zengin metin editörleri, koca kütüphaneyi çağıran anlık tarih formatlayıcıları veya tüm sisteme yayılan util modülleri zaman içinde damlayarak ilk yük (initial payload) boyutunu katlar.
Bundle boyutu yalnızca bir ağ indirme maliyeti değildir. İndirilen kodun ayrıştırılması, bellek üzerinde derlenmesi ve etkileşim anında ana iş parçacığını meşgul etmesi de denklemin büyük bir parçasıdır. Gözden kaçan gereksiz bir bağımlılık, INP ve ilk açılış tarafında yoğun hantallık üretir. Yüksek bir main chunk boyutu tarayıcı üzerinde yüzlerce milisaniyelik bloklama yaratabilir.
Tek bir kütüphaneyi suçlamak çoğu zaman yetersizdir
İlk refleks genelde en büyük alanı kaplayan pakete saldırmaktır. Bir harita veya grafik kütüphanesi saptanır ve bütün sorun ona ihale edilir. Gerçek uygulama senaryoları biraz daha karışıktır. Bazen devasa bir editör paketi dengeyi bozar; ancak daha yaygın olan senaryo, orta boyuttaki pek çok paketin, tekrar eden yardımcı modüllerin ve kontrolsüz import kararlarının birleşerek ilk yanıtı felç etmesidir.
Örneğin tarih işlemleri için projenin tamamını moment kütüphanesine boğmak, yalnızca iki yardımcı fonksiyon gerekirken kütüphanenin dil (locale) paketlerini içeri sokmak, ufak bir icon-font kullanımı için tam set ikon ailesini indirtmek, sadece yönetim panelinde (dashboard) gereken ağır bir data-table bileşenini, yönlendirmesi yapılmamış şekilde herkesin açtığı landing page’e sızdırmak. Bunların her biri tek tek ele alındığında masum görünür, fakat etkileri derleme (build) çıktısında yıkıcıdır.
Bu yüzden analiz işlemi bir cadı avı gibi değil, "veri ve istek akışı" üzerinden ilerlemelidir. Sorulması gereken kök soru şudur: Bu modül veya fonksiyon parçası neden ana index.html çağırmasına (main pack) katıldı? Bu soruyu cevaplayamadığınız her kütüphane incelemeye alınmalıdır.
Rakamları doğru konumlandırmak
Kullanılan Rollup, Webpack gibi bundle araçlarının verdiği çıktılar geliştiricilerin aklını karıştırabilir. Ham (raw) boyut, minifikasyon geçirmiş boyut, gzip ya da brotli ile preslenmiş taşıma boyutu, route-based parçalanan boyutlar birbirine karışır. Bazen tek ekranda sunulan bu metriklerin hepsi "indirme hızıymış" gibi okunur.
Ham boyut diskteki saf kodunuzdur. Aktarım boyutu ise CDN ağından çıkan pakettir. Ancak tarayıcının işlemci bütçesini tüketen şey, gzip ile paketlenmiş küçültülmüş çıktının değil, zipten çıkarıldığındaki parse maliyetidir. Bu bağlamda, dosya küçültme ve bundle analizi tamamen ayrı kulvarlardır. Minify edilmiş dosyalar ağ bant genişliğini rahatlatır; ancak kullanılmayan gereksiz kod parse maliyeti üretmeye devam eder. Yaptığınız bundle ayıklamasının ardından oluşan dosya küçültmesinin nihai ağ etkisini HTML/CSS/JS Minify aracı ile laboratuvar ortamında ayrıca doğrulayabilirsiniz.
En büyük hatalardan biri, doğrudan ilk yük ile sonradan arka planda inmesi gereken "chunk"ları birbirinden ayıramamaktır. Toplamda 4 MB büyüklüğünde dev bir e-ticaret SPA projeniz olabilir; eğer açılış anındaki home.js sayfası sadece 120 KB tüketiyorsa endişe yersizdir. Eğer ki 800 KB boyutundaki bir kargo-takip kütüphanesi, ana sayfadaki arama modülüne (main.js) doluşmuşsa o vakit sorun kritiktir.
main.js 210 KB raw 62 KB gzip
vendor-chart.js 312 KB raw 95 KB gzip
editor-panel.js 286 KB raw 88 KB gzip
date-utils.js 78 KB raw 22 KB gzip
legacy-helpers.js 64 KB raw 18 KB gzip
Böyle bir rapora bakarak en ağır paket olan vendor-chart.js öğesini direkt projeden atmak aceleci bir karar olabilir. Çünkü o grafik kütüphanesini raporlama ekranları için zaten kullanıyorsunuz. Sorulması gereken soru; bu grafik dosyasının, kullanıcının siteye girdiği o ilk karşılama (hero) sekmesinde ne aradığıdır? Yanlış modül tahsisi donanım bütçesini direkt baltalar.
Yinelenen fonksiyonları ve kopyaları saptama
Paketlerin kontrolsüz büyümesinin bir numaralı sorumlularından biri tekrarlanan kod yapısıdır. Özellikle monorepo olmayan, uzun yaşam döngüsüne sahip mikro-frontend veya monolit projelerde sık rastlanır. Yardımcı bir kütüphanenin iki faklı majör versiyonu, proje içindeki farklı klasörlere sızmış ortak (shared) fonksiyonlar, kopyalanmış util dosyaları... Ekip kodu incelediğinde bir adet bağımlılık kullanıldığını varsayar; ancak derlenen bundle'a bakıldığında aynı işlev üç farklı isimle içeri taşınmıştır.
Tarih operatörleri, lodash fonksiyonları, format çeviriciler, UI form validatörleri en klasik zanlılardır. Aynı repo içerisinde bir sayfa date-fns ile takvim ararken, fatura sayfası dayjs kullanıyor, eski bir miras kalmış kod bloğu ise moment altyapısına bağımlıysa, proje bu kargaşayı toplam 3 paket olarak çıktıya yansıtır. Her biri "hafif bir detay" olarak eklenmiştir ancak neticede gereksiz şişmanlığın temel dayanağı olup çıkarlar. Kullanılmayan kaynak temizliği burada bir adım geriden gelir. Kullanılmayan kaynak bir kalıntı temizliği işiyken; bundle analizi birden fazla bölüme saçılmış mükerrer mantığın tespiti şansıdır.
app/
features/report/chart-utils.ts
features/dashboard/chart-utils.ts
shared/chart-utils.ts
Geliştirme dizinindeki böyle bir kopya kargaşası kod okumasında fark edilmeyebilir. Fakat bundle analiz aracı, bu 3 dosyanın farklı route chunk'larına tekrar tekrar (duplicate) paketlendiğini net şekilde raporlayacaktır. Kopya kod parçaları kullanıcı gözüyle deneyimi etkilemiyor gibi görünse de tarayıcı fazladan mesai harcayıp pili ve işlemciyi sömürür.
Karar anı ve silme politikası
Kırmızı renkle patlayan her büyük kutucuğu silmek çözüm değildir. Gelişmiş bir kod görüntüleyici (Prism), kapsamlı bir harita servisi (Leaflet/Google Maps) ağır çekirdeklere sahiptir. Plan, o servisi haritadan silmek değil, ziyaretçinin sadece haritaya tıkladığında o modülün derlenip inmesini (Lazy Load) sağlamaktır.
Büyük bir servisi, yerini kendi kütüphanemle yazayım motivasyonuyla çöpe atmak, bakım yükünü gereksiz biçimde üzerinize yıkabilir. Analiz bize çözümün her zaman paketi silmek ya da baştan yazmak olmadığını gösterir; bazen daha doğru yol ertelemek, import akışını düzeltmek ya da modülü asenkron çağırmaktır. Dynamic import tam bu noktada devreye girer.
Bir paket 300 KB olabilir, ancak sayfanın temel amacı bir metin editörü sunmaksa o paket zaten kalmalıdır. Fakat 60 KB’lık önemsiz bir dil paketi, tek satırlık doğru bir import { tr } from 'date-fns/locale' kuralıyla anında 5 KB’a inebiliyorsa o fırsat derhal değerlendirilmeli ve ilk yüke asılan ağırlık kesilmelidir.
Bundle raporunu sürekli uyanık tutmak
Mevcut paket analizi projenin kriz anlarında sığınılan limanı olmamalıdır. Doğru olan usül, CI/CD pipeline süreçlerine veya versiyon kontrol takiplerine bir bundle-size denetleyicisi iliştirmektir. Yeni bir modül eklendiğinde ilk yük (main) 40 KB artıyorsa, bu yük yayına alınmadan önce gerekçesiyle beraber tartışılmalıdır.
Bu disiplin oturmadığı zaman aylar sonra yine Lighthouse skorları düşecek, etkileşim yavaşlaması şikayetleri artacak ve dev bir geri alma (refactor) operasyonu başlatılacaktır. Kısa iterasyonlarla "Hangi rota ne kadar genişledi?" sorusunu sormak her zaman o kaba kuvvet operasyonundan hesaplıdır.
Ekibin bu rutinleri performans kültürünü doğrudan somut veriye odaklar. "Sitemiz neden yavaşlıyor?" sorusunu belirsiz bırakmak yerine, "Bugünkü sprint ilk paketi 80 KB ağırlaştırdı, bunu parçalayabilir miyiz?" gibi net bir çerçeveyle konuyu mühendislik zeminine taşımış olursunuz.