Angular延遲載入(Lazy Loading)設定

預設情況下 NgModules 都是Eager Loading(急切載入)的,這意味一開始進入首頁,所有的 NgModules 無論是否需要都會被載入,使用Lazy Loading(延遲載入)功能,會等到Module內的元件有需要使用時才載入,延遲加載有助於讓初始化的檔案保持為較小的大小,從而減少加載的時間。

舉例來說,如果網站頁面有一個PageModule,底下又分別有2個Module

  • HomeModule:存放主頁面的相關元件
  • AdminModule:存放管理員功能的相關元件

其實在一開始我們只需要HomeModule裡面的元件來呈現主要畫面,AdminModule並不需要在一開始就載入。如果在一開始就載入用不到的AdminModule反而會增加了網頁的載入時間,這時候就可以把AdminModule設成延遲載入,等到點選按鈕切換路由到管理員相關頁面後,才進行Module的載入。

接下來就來實作Lazy Loading的範例(範例專案)。


Lazy Loading設定

首先,要先到AppRoutingModule裡面把admin路由的component屬性換成loadChildren。告訴AppRoutingModule,AdminModule要採用Lazy Loading的方式來載入。

[*]AppRoutingModule:

const routes: Routes = [
  {path: '', component: MainComponent },
  {path: 'main', component: MainComponent },
  {
    path: 'admin',
    loadChildren: () => import('./pages/admin/admin.module').then(m => m.AdminModule)
  },
  {path: '**', redirectTo: 'main' },//沒有比對到路由,要放到最後面
];

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

接著新增一個AdminRoutingModule,來設定實際要被載入的元件(component)的路由

[+]AdminRoutingModule:

const routes: Routes = [
  {path: '', component: AdminComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})

export class AdminRoutingModule { }

然後在AdminModule裡面匯入AdminRoutingModule

@NgModule({
  declarations: [AdminComponent],
  imports: [
    CommonModule,
    AdminRoutingModule
  ],
  exports:[AdminComponent]
})
export class AdminModule { }

這樣子就把AdminModule設定成延遲載入模式了


測試Lazy Loading是否生效

我們可以進入AppRoutingModule的admin路由,看看是否有載入AdminModule。結果看起來進入/admin路由後,什麼事情都沒有發生。如果Lazy Loading有生效的話,應該會在這時候才載入相關的.js檔案。

檢查Lazy Loading為何沒有生效

原來是AppModule匯入了PageModule,而PageModule裡面又包含了HomeModule跟AdminMdule,導致AdminModule的元件在一開始的AppModule就被載入了(所有的Javascript都會被包在main.js裡面在初始路由就被載入了)。

PageModule:

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    HomeModule,
    AdminModule
  ],
  exports:[
    HomeModule,
    AdminModule
  ]
})
export class PagesModule { }

AppRoutingModule:

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

知道原因後,我們把AdminModule從PageModule中移除

PageModule:

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    HomeModule
  ],
  exports:[
    HomeModule
  ]
})
export class PagesModule { }

接著再我們可以進入admin路由,看看是否有載入AdminModule。看起來Lazy Loading是有生效了,AdminModule的js等到進入admin路由時才被載入。

 

以上就是Angular設定Lazy Loading的流程。


Ref: