Angular 8 – Dynamic Imports For Lazy Loading

Merhaba,

Bu içeriğimizde Angular 8 ile gelen dynamic imports for lazy routes yeniliği üzerine konuşuyor olacağız. Esasında Lazy Loading Angular mimarisi için pekte yeni bir özellik sayılmaz. Önceki yazılarımda, kâh Angular ile ilgili yazı dizimizde kâh diğer makalelerimizde Angular’da Lazy Loading mekanizmasından hiç bahsetmemiş olduğumdan dolayı ilgili içeriğimizde öncelikle Angular’ın önceki sürümlerinde Lazy Loading mekanizmasının neye yaradığını ve nasıl kullanıldığını konuşacağız ve bununla beraber Angular 8’de söz konusu mekanizma üzerinde nasıl bir yenilik gerçekleştirildiği hakkında irdelemede bulunacağız.

Lazy Loading Nedir?

Hiç bilmeyenler için lazy loading’i izah edersek eğer Tembel Yükleme diyebiliriz. Yani bir uygulamayı komple bir bütün olarak clienta indirtmektense kullandıkça parça parça indirmesini sağlamaktır. Bu web uygulamalarında yapmış olduğumuz Scroll Paging yahut sayfada ekrana geldikçe fotoğrafların geç yüklenmesi olayının ta kendisidir…

Angular uygulamalarında Lazy Loading, uygulama ayağa kaldırılır kaldırılmaz tüm componentlerin derlenip tarayıcıya hepsinin birden kaba tabirle bodoslama yüklenmesinden ziyade yapılan isteklere karşılık parça parça yüklenmesini sağlayan bir mekanizmadır. Burada mühim olan nokta şudur ki, bir component lazy loading ile yüklendikten sonra ilgili componente yapılan tüm isteklerde bir daha yüklenme işlemi gerçekleşmeyecek ve önceki yüklenen component tarafımıza geri döndürülecektir. Buda ekstradan performans açısından verim demektir…

Şimdi Angular’da lazy loading’i inceleyebilmek için herşeyden önce makalemizde kullanacağımız componentleri aşağıdaki gibi oluşturalım;

ng g c components/personels/ekle --spec false
ng g c components/personels/listele --spec false
ng g c components/personels/detay --spec false   
ng g c components/musteris/ekle --spec false
ng g c components/musteris/listele --spec false
ng g c components/musteris/detay --spec false

Görüldüğü üzere “musteri” ve “personel” operasyonları için “ekle”, “listele” ve “detay” olmak üzere üçer tane component oluşturmuş bulunmaktayız. Şimdi gelin ilk olarak bu componentleri lazy loading kullanmaksızın uygulamamızı inşa edelim.

Lazy Loading Kullanılmadığı Durum

Uygulamada kullanılan tüm componentleri direkt olarak kullanabilmek için ana dizinde oluşturulmuş ve route yapılanmasından sorumlu “AppRoutingModule” üzerinden url rotalarını ayarlıyoruz.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EkleComponent } from './components/personels/ekle/ekle.component';
import { ListeleComponent } from './components/personels/listele/listele.component';
import { DetayComponent } from './components/personels/detay/detay.component';

import { EkleComponent as MusteriEkle} from './components/musteris/ekle/ekle.component';
import { ListeleComponent as MusteriListele } from './components/musteris/listele/listele.component';
import { DetayComponent as MusteriDetay } from './components/musteris/detay/detay.component';

const routes: Routes = [
  { path: "personel/ekle", component: EkleComponent },
  { path: "personel/listele", component: ListeleComponent },
  { path: "personel/detay/:id", component: DetayComponent },
  { path: "musteri/ekle", component: MusteriEkle },
  { path: "musteri/listele", component: MusteriListele },
  { path: "personmusteriel/detay/:id", component: MusteriDetay },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Bu işlem neticesinde artık bu componentleri direkt kullanabiliriz. “app.component.html” dosyasına gelip aşağıdaki gibi bir tasarımsal çalışmada bulunuyoruz.

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" routerLink="personel/ekle">Personel Ekle <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" routerLink="personel/listele">Personelleri Listele <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" routerLink="musteri/ekle">Müşteri Ekle <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" routerLink="musteri/listele">Müşterileri Listele <span class="sr-only">(current)</span></a>
      </li>
      
    </ul>
  </div>
</nav>

<router-outlet></router-outlet>

Uygulamayı derleyip yayına aldığımızda aşağıdaki ekran görüntüsünde olduğu gibi tüm componentler tek seferde yüklenmiş bulunmaktadır.
Angular 8 - Dynamic Imports For Lazy Loading

Angular 8’den Önceki Lazy Loading Kullanımı

Angular uygulamalarında Lazy Loading uygulayabilmek için yapılması gereken temel esas şudur ki, her bir component ya da component kümesi için ayrı bir module oluşturmalı ve bu modülleri uygulamaya loadChildren olarak refere etmeliyiz. Bu işlem Angular 8 sürümü içinde geçerlidir. Şimdi Angular 8’den önceki sürümlerde lazy loading’in nasıl yapılandırıldığını konuşalım. Ardından esas konumuz olan Angular 8 ile lazy loading yapılandırmasına gelen yeniliği ele alacağız.

Şimdi ilk olarak senaryodaki müşteri ve personel componentlerini karşılayacak olan birer modül oluşturalım.
– MusterisModule

ng g m components/musteris
ng g m components/personels

Ardından sırasıyla bu modüller içerisinde ilgili componentlerin route yapılanmasını tasarlayalım.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { EkleComponent } from './ekle/ekle.component';
import { ListeleComponent } from './listele/listele.component';
import { DetayComponent } from './detay/detay.component';

@NgModule({
  declarations: [EkleComponent, ListeleComponent, DetayComponent],
  imports: [
    CommonModule,
    RouterModule.forChild([
      { path: "ekle", component: EkleComponent },
      { path: "listele", component: ListeleComponent },
      { path: "detay/:id", component: DetayComponent },
    ])
  ]
})
export class MusterisModule { }

– PersonelsModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { EkleComponent } from './ekle/ekle.component';
import { ListeleComponent } from './listele/listele.component';
import { DetayComponent } from './detay/detay.component';

@NgModule({
  declarations: [EkleComponent, ListeleComponent, DetayComponent],
  imports: [
    CommonModule,
    RouterModule.forChild([
      { path: "ekle", component: EkleComponent },
      { path: "listele", component: ListeleComponent },
      { path: "detay/:id", component: DetayComponent },
    ])
  ]
})
export class PersonelsModule { }

Burada her ne kadar sizin gözünüzden kaçmayacağına emin olsamda yinede ben tekrardan hatırlatmak istiyorum ki, modüllerde eklenen componentleri “declarations” özelliğine eklemeyi unutmayınız…

Bu adımdan sonra yapılması gereken, oluşturulan bu modülleri uygulamanın ana routing mekanizması olan “AppRoutingModule” dosyasında aşağıdaki gibi import ederek, modüler entegrasyon üzerinden uygulamayı kurgulamayı ve böylece lazy loading mekanizmasından da faydalanmayı sağlamamız gerekmektedir.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: "musteri", loadChildren: "./components/musteris/musteris.module#MusterisModule" },
  { path: "personel", loadChildren: "./components/personels/personels.module#PersonelsModule" },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Yukarıdaki routes tanımlamasını incelerseniz eğer, oluşturulan path’in karşılığını “loadChildren” özelliği ile elimizdeki modülerin dizinlerini göstererek belirtmekteyiz. Angular 8’den önceki sürümlerde özellikle bu tanımlamada ilgili modülün class name değerini “#”(diyez) karakteri ile ilgili dizin değerinin sonuna belirtmemiz gerekiyor.

Ve son olarak ana modülümüz olan “AppModule” sınıfınıda aşağıdaki gibi ele alalım.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Dikkat ederseniz eğer “AppModule” sınıfında oluşturduğumuz modüllerimizden herhangi birini import etmemekteyiz. Çünkü gerekli import işlemi “AppRoutingModule” sınıfında gerçekleştirilmiştir.

Şimdi uygulamayı derleyip ayağa kaldıralım ve modüler yapılanma ile elde edilen uygulama üzerinden yapılan istekler eşliğinde her bir componentin istek neticesinde yüklendiğini gözlemleyelim.
Angular 8 - Dynamic Imports For Lazy Loading
Görüldüğü üzere uygulamada componentleri local modüller üzerinden “loadChildren” ile referans ettiğimiz taktirde lazy loading mekanizması devreye girmekte ve componentlerimiz istekler neticesinde ihtiyaca istinaden yüklenmektedir.

İşte Angular 8 öncesi lazy loading kullanımı bu şekilde gerçekleştirilmektedir. Peki hocam, Angular 8’de ki yenilik ne ola ki? sorunuzu duyar gibiyim… Hadi fazla sabrınızı sınamadan esas konumuza gelelim.

Angular 8 Lazy Loading Kullanımı

Angular mimarisinde lazy loading rotalarının metinsel olarak belirtilmesinden ve böylece yapılan dizin yahut isim hatasından dolayı olası hataların meydana gelme riskinin artmasından dolayı dinamik içe aktarma sözdizimi kullanılmak üzere Angular 8 sürümünde yeni bir özellik gelmektedir. Dolayısıyla, yolu yanlış girilen ya da ismi hatalı belirtilen modülün daha rahat ayırt edilebilmesi beklenmekte ve alınacak hataların kaynağı doğrudan algılanabileceği düşünülmektedir. Velhasıl en nihayetinde Dynamic Imports For Lazy Loading yeniliğini kullanabilmek için “AppRoutingModule” sınıfında tasarlanan rotaları aşağıdaki gibi import etmemiz yeterlidir.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: "musteri", loadChildren: () => import("./components/musteris/musteris.module").then(x => x.MusterisModule) },
  { path: "personel", loadChildren: () => import("./components/personels/personels.module").then(x => x.PersonelsModule) },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Evet… Böylece Angular 8’de gelen Lazy Loading sözdizimindeki yeniliği, önceki sürümlerle mukayese niteliğinde incelemiş ve değerlendirmiş olduk.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*