原文链接:https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html
使用模块来组合我们应用程序的相关功能的另一个优点是能够根据需要加载这些片段。 Lazy加载模块可帮助我们减少启动时间。 通过懒惰加载,我们的应用程序不需要一次加载所有内容,只需要加载用户在首次加载应用程序时看到的内容。 只有当用户导航到他们的路由时,才会加载懒惰加载的模块。
为了展现这种关系,我们首先定义一个简单的模块,作为我们示例应用程序的根模块。
app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { EagerComponent } from './eager.component';
import { routing } from './app.routing';
@NgModule({
imports: [
BrowserModule,
routing
],
declarations: [
AppComponent,
EagerComponent
],
bootstrap: [AppComponent]
})
export class AppModule {}
到目前为止,这是一个非常常见的模块,依赖于BrowserModule ,具有routing机制和两个组件: AppComponent和EagerComponent 。 现在,让我们关注我们的应用程序( AppComponent )的根组件,其中定义了导航。
app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>My App</h1>
<nav>
<a routerLink="eager">Eager</a>
<a routerLink="lazy">Lazy</a>
</nav>
<router-outlet></router-outlet>
`
})
export class AppComponent {}
我们的导航系统只有两条路: eager和lazy 。 要知道在点击这些路径时加载哪些路径,我们需要查看我们传递给根模块的routing对象。
app/app.routing.ts
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { EagerComponent } from './eager.component';
const routes: Routes = [
{ path: '', redirectTo: 'eager', pathMatch: 'full' },
{ path: 'eager', component: EagerComponent },
{ path: 'lazy', loadChildren: 'lazy/lazy.module#LazyModule' }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
这里我们可以看到我们应用程序中的默认路径叫做eager ,它会加载EagerComponent 。
app/eager.component.ts
import { Component } from '@angular/core';
@Component({
template: '<p>Eager Component</p>'
})
export class EagerComponent {}
但更重要的是,我们可以看到,每当我们尝试去lazy的路径时,我们将懒惰地加载一个方便地称为LazyModule的模块。 仔细观察该路线的定义:
{ path: 'lazy', loadChildren: 'lazy/lazy.module#LazyModule' }
这里有一些重要的事情要注意:
我们使用属性loadChildren而不是component 。
我们传递一个字符串而不是一个符号,以避免加载模块。
我们不仅定义了模块的路径,而且还定义了类的名称。
LazyModule没有什么特别之处,除了它有自己的routing和一个名为LazyComponent的组件。
app/lazy/lazy.module.ts
import { NgModule } from '@angular/core';
import { LazyComponent } from './lazy.component';
import { routing } from './lazy.routing';
@NgModule({
imports: [routing],
declarations: [LazyComponent]
})
export class LazyModule {}
如果我们将类LazyModule定义为文件的default导出,我们不需要在loadChildren属性中定义类名,如上所示。
routing对象非常简单,仅定义在导航到lazy路径时加载的默认组件。
app/lazy/lazy.routing.ts
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LazyComponent } from './lazy.component';
const routes: Routes = [
{ path: '', component: LazyComponent }
];
export const routing: ModuleWithProviders = RouterModule.forChild(routes);
请注意,我们使用方法调用forChild而不是forRoot来创建路由对象。 当为特征模块创建路由对象时,我们应该始终这样做,无论该模块是如何被热切地或者懒惰地加载的。
最后,我们的LazyComponent非常类似于EagerComponent ,只是一些文本的占位符。
app/lazy/lazy.component.ts
import { Component } from '@angular/core';
@Component({
template: '<p>Lazy Component</p>'
})
export class LazyComponent {}
当我们第一次加载我们的应用程序时, AppModule沿AppComponent将被加载到浏览器中,我们应该看到导航系统和文本“Eager Component”。 直到此时, LazyModule尚未下载,只有当我们点击链接“Lazy”时,所需的代码将被下载,我们将在浏览器中看到消息“Lazy Component”。
我们有效地懒惰地加载了一个模块。