Bir üretim build'i tamamlandığında terminalde görünen dosya boyutları genellikle yanıltıcıdır. main.js: 1.2 MB satırı sorunun nerede olduğunu söylemez; yalnızca bir şeylerin yanlış gittiğini hissettirir. Webpack Bundle Analyzer tam bu noktada devreye girer: build çıktısını interaktif bir treemap olarak görselleştirir ve hangi modülün toplam boyuta ne kadar katkıda bulunduğunu gösterir.

Aracı açmak çözümün yalnızca başlangıcıdır. Treemap'i doğru okumak, hangi sayıya bakmak gerektiğini bilmek ve çıkan sonuçtan doğru kararı üretmek ayrı bir beceridir. Yanlış yorumlama, hiç incelememe kadar zararlı olabilir: küçük bir kütüphaneyi optimize etmeye odaklanırken asıl şişkinliği gözden kaçırmak sık karşılaşılan bir tuzaktır.

Treemap alanının ne anlama geldiğinden, yinelenen modüllerin nasıl tespit edileceğine ve hangi paketin neden çıkarılması gerektiğine kadar her adım aşağıda ele alınıyor.

Treemap Alanı Neyi Temsil Eder?

Analyzer'ı ilk açtığınızda iç içe geçmiş dikdörtgenlerden oluşan bir harita görürsünüz. Dış dikdörtgenler bir chunk'ı temsil eder; bu main, vendor ya da dinamik import ile oluşturulan bir async-chunk olabilir. İçlerindeki küçük dikdörtgenler ise o chunk'ta yer alan bireysel modüllerdir. Her dikdörtgenin alanı, ilgili modülün bundle'a katkısıyla doğru orantılıdır.

Görsel aldatmaz. Büyük görünen gerçekten büyüktür. Ancak hangi büyüklüğe baktığınız, vardığınız sonucu belirler: araç varsayılan olarak "parsed" boyutu gösterir, yani JavaScript motorunun ayrıştıracağı minification sonrası boyutu, ve bu değer ağ üzerinde giden boyuttan belirgin şekilde farklı olabilir.

Rakamları somutlaştırmak gerekirse: 400 KB parsed boyutundaki bir kütüphane, gzip sonrasında 80-120 KB arasına düşebilir. Bu fark, hangi paketi önce inceleyeceğinizi değiştirebilir; çünkü boyut sıralaması parsed ve gzip değerlerinde her zaman aynı değildir. Bazı kütüphaneler metin sıkıştırmadan çok daha fazla yararlanır, dolayısıyla ağ maliyetleri birbirinden belirgin şekilde ayrışır.

Treemap'te bir modülü tıkladığınızda o modülün hangi chunk'ta bulunduğunu ve nereden çekildiğini görebilirsiniz. Aynı isimli bir modülü birden fazla chunk'ta görüyorsanız yineleme sorunuyla karşı karşıyasınızdır; buna ayrı bir bölümde dönüyoruz.

Stat, Parsed ve Gzip: Hangi Boyuta Bakmalısınız?

Bundle Analyzer üç farklı boyut türü gösterir. Bunları karıştırmak yanlış kararlara yol açar.

Stat boyutu, minification ve tree shaking uygulanmadan önce bundler'ın gördüğü ham kaynak boyutudur. Gerçek üretim boyutunu yansıtmaz ama bir kütüphanenin ne kadar "şekillendiğini" anlamak için kullanışlıdır. Stat ile parsed arasındaki fark büyükse tree shaking ve minification iş yapıyor demektir; fark küçükse kütüphane büyük ihtimalle CommonJS formatındadır ve tree shaking'den yararlanamamaktadır.

Parsed boyutu, minification ve tree shaking sonrasında tarayıcının ayrıştıracağı dosyanın gerçek boyutudur. Performans tartışmalarında en kritik sayı burasıdır; parse maliyeti, ağ boyutundan bağımsız olarak özellikle düşük performanslı cihazlarda sayfayı yavaşlatır ve bu maliyet JavaScript'in toplam boyutuyla orantılı biçimde artar.

Gzip boyutu ise gerçek ağ maliyetini gösterir. Sunucunuzda sıkıştırma açıksa bu değer, kullanıcıların indireceği boyutu yaklaşık olarak yansıtır. Brotli kullanıyorsanız gerçek boyut bundan daha da düşük olacaktır.

Karar sürecinde önce parsed boyutuna bakın, ardından gzip değeriyle orantıyı kontrol edin. Her iki değeri de optimizasyon öncesi ve sonrası karşılaştırma referansı olarak kaydedin; chunk bölme ve minify yapılandırmasını doğru kurmak bu sayıları doğrudan etkiler.

Yinelenen Modülleri Nasıl Tespit Edersiniz?

Yinelenen modüller, bundle boyutunu sessizce şişiren sorunların başında gelir. Aynı kütüphanenin farklı versiyonları, farklı bağımlılıklar tarafından çekildiğinde treemap'te birden fazla kez görünür. Bu durum özellikle lodash, date-fns ve tslib gibi yaygın araç kütüphanelerinde sık karşılaşılır.

Fark etmek için treemap'in arama özelliğini kullanın. Bir kütüphane adını filtreleyin: eğer farklı yollarla (node_modules/a/node_modules/lodash ve node_modules/lodash gibi) birden fazla sonuç çıkıyorsa o kütüphane iki kez bundle'a giriyor demektir.

Yinelemenin kaynağını anlamak için terminalde npm ls [paket-adı] ya da Yarn kullanıyorsanız yarn why [paket-adı] komutunu çalıştırın. Bu, hangi bağımlılığın farklı versiyonu çektiğini gösterir. Aynı semantik versiyona denk düşen kopyalar, webpack'in resolve.alias seçeneğiyle ya da Yarn'ın resolutions alanıyla birleştirilebilir.

Yineleme her zaman giderilebilir değildir; bir bağımlılık kasıtlı olarak farklı bir versiyona ihtiyaç duyuyor olabilir. Zorla birleştirmek bu durumda çalışma zamanı hatalarına yol açar. Chunk sınırlarını doğru çizmek yinelemenin hangi chunk'larda ne kadar hasar verdiğini görünür kılar ve çözülebilen kopya sayısını artırır.

Hangi Paketi Neden Çıkarmak Gerekir?

Büyük bir dikdörtgen gördünüz. Hemen kaldırmak gerekiyor mu? Karar vermeden önce üç soruyu yanıtlayın.

İlk soru: bu kütüphane gerçekten kullanılıyor mu? Bazı paketler yalnızca bir veya iki özellik için çekilmiş olabilir. Geliştirme bağımlılıklarının production build'e karıştığı durumlar da görülür; bunu kontrol etmenin en kısa yolu webpack yapılandırmasında mode: 'production' ayarının açık olduğunu doğrulamaktır. Bazı araçlar development modunda test yardımcıları veya debug çıktıları ekler ve bunlar production'a sızabilir.

İkinci soru: bu kütüphanenin işlevini daha hafif bir alternatifle karşılamak mümkün mü? Yalnızca tarih formatlama için moment kullanıyorsanız Intl.DateTimeFormat ile yerel bir çözüm aynı işi çok daha küçük boyutla görür. Tüm lodash'ı çekmek yerine yalnızca ihtiyaç duyulan fonksiyonu ayrı import etmek de belirgin fark yaratır. State yönetim kütüphanesinin seçimi de bu soruyu doğrudan etkileyen kararlardan biridir.

Üçüncü soru: değiştirmenin riski ne? Kütüphane uygulamanın geniş bir bölümüne yayılmışsa, biriken bağımlılık yükünü çözmenin maliyeti kazanılan boyutun çok üzerinde olabilir. Kütüphane yalnızca tek bir sayfaya özel bir özellik için gerekiyorsa, silmek yerine dynamic import ile ilgili sayfanın chunk'ına taşımak genellikle daha güvenli ve etkili bir yaklaşımdır.

Tree Shaking Çalışıyor mu? Treemap'ten Nasıl Anlarsınız?

Tree shaking, import edilmeyen kodun bundle dışında bırakılması sürecidir. Çalışıyor mu? Bunu doğrudan treemap'ten okumak mümkündür.

Stat boyutu ile parsed boyutunu karşılaştırın. Bir kütüphanenin stat boyutu 200 KB iken parsed boyutu 180 KB ise tree shaking neredeyse hiç çalışmıyor demektir. Farklı bir senaryoda stat 200 KB iken parsed 30 KB ise kütüphanenin büyük bölümü elenmiş demektir.

Sorun çoğunlukla import biçiminden kaynaklanır. import _ from 'lodash' yerine import { debounce } from 'lodash' yazmak yeterli değildir; kütüphanenin ESM formatında yayımlanmış olması gerekir. CommonJS ile paketlenmiş bir kütüphane, named import kullansanız da tree shaking'den yararlanamaz ve tüm kütüphane bundle'a girer.

Bunu treemap'te şöyle fark edersiniz: tek bir fonksiyon import ettiğinizi bildiğiniz bir kütüphane, tüm kaynak boyutuna yakın bir parsed değer gösteriyorsa CommonJS sorunu yaşıyor olma ihtimali yüksektir. Kütüphanenin package.json dosyasında module ya da exports alanının varlığını kontrol etmek, durumu hızlıca netleştirir.

Async Chunk'ları ve Code Splitting'i Okumak

Code splitting doğru çalışıyorsa treemap birden fazla chunk içerecektir; bunlardan biri ilk yüklemede indirilen ana chunk, diğerleri ise sayfa geçişlerinde ya da belirli etkileşimlerde yüklenen async chunk'lardır. İyi bir yapılandırmada ilk yükleme chunk'u küçük, async chunk'lar bağımsız ve mantıklı şekilde gruplanmış olur.

Sorun nereden görülür? Ana chunk beklenmedik şekilde büyük olduğunda, içinde hangi modüllerin olduğuna bakın. Yalnızca belirli bir akış için gerekli olan bir kütüphane ana chunk'ta yer alıyorsa, o kütüphane bir dynamic import ile ikincil chunk'a taşınabilir. Tersine, aynı modül hem ana chunk'ta hem de birden fazla async chunk'ta görünüyorsa webpack'in splitChunks yapılandırması bu modülü ortak bir chunk'a çıkarmıyor olabilir.

Çok küçük chunk'lara dikkat edin. Code splitting'in her şey için uygulanması, her biri 2-5 KB olan onlarca HTTP isteği oluşturabilir; bu durum HTTP/2 olsa bile ek round-trip maliyeti nedeniyle fayda yerine zarar üretebilir. Hangi sayfalara ne sıklıkla gidildiğini bilmeden chunk sınırı çizmek, sıkça gidilen sayfaların yükünü artırabilir. Yayına çıkmadan önce bundle boyutlarını sistematik biçimde kontrol etmek bu tür dengesizlikleri erken yakalamanın pratik yollarından biridir.

Analiz Sonrası Karar Öncelik Sırası

Bundle Analyzer çalıştırdınız, notlar aldınız. Şimdi ne yapacaksınız? Öncelik sırasını belirlemek, dağınık bir liste üzerinde rasgele hareket etmekten çok daha hızlı sonuç verir.

Önce düşük riskli, yüksek kazançlı adımları ele alın. Yinelenen modülleri birleştirmek genellikle bu kategoriye girer; yapısal bir değişiklik gerektirmez, test edilmesi nispeten kolaydır. Ardından production'a karışan development bağımlılıklarını temizleyin; bu da güvenli ve ölçülebilir bir kazanımdır.

Orta seviyede, tree shaking çalışmayan ama ESM alternatifi bulunan kütüphaneleri değiştirin. Bu adım biraz araştırma gerektirir ama toplam parsed boyutunu belirgin şekilde düşürebilir. En son, büyük kütüphanelerin async chunk'lara taşınmasını ya da mimari değişiklik gerektiren bölümleri planlayın; bu adımlar daha yüksek test kapsamı ve dikkat gerektirir.

Her adım sonrasında build'i yeniden çalıştırın ve hem parsed hem gzip boyutlarını kaydedin. Bir değişiklik, beklentinin altında ya da üstünde etki gösterebilir; bunu yalnızca ölçerek anlarsınız. Büyük projelerde bu ölçüm döngüsünü disipline bağlamak ilerleyen zamanlarda şişkinliğin sessizce geri dönmesini engeller.

Bundle Analyzer, bir anda her şeyi çözen bir araç değil; doğru soruları sormaya yardımcı olan bir teşhis aracıdır. Büyük bir dikdörtgen gördüğünüzde ilk tepki kaldırmak değil, anlamak olmalıdır: bu boyut neden burada, gerçekten gerekli mi, daha hafif bir yolla karşılanabilir mi?

Treemap'i düzenli olarak incelemek alışkanlık haline geldiğinde, boyut şişkinliği birikimine karşı erken uyarı sistemi işlevi görür. Yeni bir bağımlılık eklendiğinde ya da mevcut bir kütüphanenin büyük versiyonu alındığında, etkiyi build çıktısında hemen görmek; sonradan yüzlerce satırı gözden geçirmekten çok daha az maliyet doğurur.