ANGULAR LAZY LOADING NEDİR?
Başlangıçta 200 KB olan bir Angular uygulamasının main bundle'ı, altıncı ekran eklendikten sonra 2.4 MB'a fırladı. Üç saniyede açılan ekran şimdi sekiz saniyede zar zor görünür hale geldi. Lighthouse'un performans skoru 92'den 41'e düştü. Lazy loading tam olarak bu probleme tasarlanmış mimari bir araçtır — kullanıcının görmediği kodu, görmediği sürece tarayıcıya hiç indirmemek. Tek sayfa uygulamalarının büyüdükçe yavaşlaması engellenemez bir kader değil; doğru route stratejisiyle kaçınılabilen bir hata. Bu yazı; Angular geliştiriciler, mobil-first proje sahibi ürün ekipleri ve performans bütçesi kovalayan ön yüz takımları için yazıldı.
Bundle Şişmesi ve Tek Sayfa Uygulamaların Çıkmazı
SPA mimarisinin ilk satış argümanı şuydu: kullanıcı uygulamayı bir kez indirir, sonrası anında akıcı bir deneyim yaşar. Pratikte iş tersine döndü. Uygulama büyüdükçe ilk indirme paketi öyle bir hâl aldı ki kullanıcı sabırsızlanıp sekmeyi kapatmaya başladı. Özellikle mobil cihazlarda 3G/4G bağlantıda 2 MB'lık bir JavaScript paketi, parse + execute süresiyle birlikte kolaylıkla 6-10 saniyeyi bulur.
Asıl ironi şu: kullanıcı çoğu zaman uygulamanın yalnızca dörtte birini kullanır. Login ekranına gelen biri admin panelinin kodunu indirmek zorunda mı? Cevap hayır olmalı. Lazy loading bunu pratiğe döken Angular'ın hazır altyapısıdır. Angular'ın resmi geliştirici kaynakları bu mimariyi route konfigürasyonuyla doğrudan destekler.
Lazy Loading Mantığı Nasıl Çalışır
Temel fikir basit: bir route ziyaret edilene kadar o route'a ait kod parçası (chunk) tarayıcıya gönderilmez. Angular CLI build sırasında her lazy module için ayrı bir JavaScript dosyası üretir. Build çıktısı şuna benzer:
- main.js — uygulama kabuğu, router, ortak servisler
- chunk-admin.js — sadece /admin route'una girildiğinde indirilir
- chunk-reports.js — /reports altına girildiğinde indirilir
- chunk-settings.js — kullanıcı ayar sayfasını açmazsa hiç indirilmez
Tarayıcı bu chunk'ları HTTP/2 üzerinden gerektiğinde, paralel olarak ister. İlk ekran daha az JavaScript ile açılır; First Contentful Paint ve Time to Interactive metrikleri belirgin biçimde iyileşir.

Route Bazlı Lazy Loading Uygulaması
Klasik NgModule yapısında lazy loading loadChildren ile yapılır. Module'ün doğrudan import edilmesi yerine dinamik import() sözdizimi kullanılır:
const routes: Routes = [
{
path: 'admin',
loadChildren: () =>
import('./admin/admin.module').then(m => m.AdminModule)
},
{
path: 'reports',
loadChildren: () =>
import('./reports/reports.module').then(m => m.ReportsModule)
}
];Burada kritik nokta dinamik import'tur. Webpack/esbuild bu sözdizimini gördüğünde otomatik olarak ayrı bir chunk üretir. Statik import { AdminModule } from './admin/admin.module' yazılırsa modül main bundle'a dahil edilir ve lazy loading bozulur.
Standalone Component ile Lazy Loading
Angular 14 ile gelen, 16-17 sürümlerinde olgunlaşan standalone component yaklaşımı NgModule zorunluluğunu kaldırdı. Lazy loading hâlâ mevcut — ama artık loadComponent kullanılır:
const routes: Routes = [
{
path: 'profile',
loadComponent: () =>
import('./profile/profile.component')
.then(m => m.ProfileComponent)
}
];Tek bir component'i lazy yüklemek module sarmalama yükünü ortadan kaldırır. Küçük proje veya ekran bazlı bölme yapan büyük projeler için yazımı daha sade, build çıktısı daha küçüktür. Standalone yaklaşıma geçen ekipler tipik olarak %15-25 oranında chunk boyutu düşüşü raporluyor.
Preloading Stratejileri
Lazy loading'in tipik şikayeti şudur: kullanıcı bir lazy route'a tıkladığında chunk inene kadar küçük bir gecikme yaşar. Angular bu gecikmeyi azaltmak için preloading sunar. Üç temel strateji vardır:
- NoPreloading — varsayılan. Hiçbir lazy chunk önceden indirilmez.
- PreloadAllModules — ana sayfa yüklenir yüklenmez tüm lazy chunk'lar arka planda indirilir. Hızlı ama bandwidth yer.
- Custom Preloading Strategy — route metadata'sına bakarak hangi modülün önceden indirileceğine geliştirici karar verir.
Pratikte en sağlam yaklaşım idle preload diye anılan custom strateji: kullanıcı ana ekranda 2-3 saniye etkileşimsiz kalırsa requestIdleCallback ile önemli chunk'lar arka planda indirilir. Hem ilk açılış hızlı kalır hem sonraki route geçişleri anlık görünür.

Lazy Loading'in Yaygın Tuzakları
Konsepti benimseyen ekiplerin sık karşılaştığı sorunlar var:
- Servis çoklanması: Lazy loaded modülde
providersdizisine eklenen servis o modül için yeni bir instance üretir.providedIn: 'root'kullanılmazsa state ikiye bölünür. - SharedModule cycle: Bir lazy modülden başka bir lazy modüle erişim cycle oluşturabilir. Ortak parçalar standalone component olarak ayrılırsa cycle riski düşer.
- Yanlış chunk granülerliği: Her component'i ayrı lazy yapmak HTTP request sayısını şişirir. Sayfa bazlı ya da feature bazlı bölme genelde optimum.
- Guard yan etkisi:
canLoadguard'ı false dönerse chunk hiç indirilmez. Kullanıcının yetkisi sonra değişirse manuel yenileme gerekebilir.
Performans Ölçümü
Lazy loading uygulaması bittikten sonra net rakamla doğrulamak şart. Üç araç işe yarar: Chrome DevTools Network sekmesinde main bundle boyutu, Lighthouse'da Total Blocking Time, ng build --stats-json çıktısının webpack-bundle-analyzer ile incelenmesi. Lazy loading öncesi ve sonrası rakamları kayıt altına almadan "iyileşti" demek subjektif kalır.
Angular performans patikasını uygulamalı yürütmek isteyenler Angular eğitimi üzerinden route mimarisi, lazy loading ve change detection optimizasyonu konularını yapılandırılmış biçimde öğrenebilir.
Ne Zaman Lazy Loading Yapmamalı
Her route lazy olmak zorunda değildir. Login, error sayfası, 404 gibi neredeyse her kullanıcının gördüğü ekranlar lazy olursa hem chunk request'i ekstra gecikme yaratır hem de cache faydası azalır. Ana akış üzerindeki kritik 2-3 ekran eager kalmalı, geri kalan feature alanları lazy bölünmelidir. Ölçü; "kullanıcı şu route'u oturumun ilk 5 saniyesinde görür mü?" sorusudur. Cevap evetse eager, hayırsa lazy.



