使用路由级代码拆分,提升应用的性能!
这篇博文将介绍如何在 Angular 应用中设置路线级代码拆分,这可以缩减 JavaScript 软件包的大小并显著缩短可交互时间。
您可以在 GitHub 上找到本文中的代码示例。Eager 分支中提供了 Eager 路由示例。路由级代码拆分示例位于延迟分支中。
为什么代码拆分很重要
随着 Web 应用的复杂性不断增加,提供给用户的 JavaScript 数量大幅增加。大型 JavaScript 文件可能会明显延迟互动,因此这项资源成本可能很高,尤其是在移动设备上。
若要在不牺牲应用功能的情况下缩减 JavaScript 软件包,最有效的方法是引入激进的代码拆分。
代码拆分可让您将应用的 JavaScript 拆分为多个与不同路由或功能相关联的区块。这种方法只会在应用初始加载期间向用户发送他们需要的 JavaScript,从而缩短加载时间。
代码拆分技术
代码拆分可在两个级别进行:组件级别和路由级别。
- 在组件级代码拆分中,您需要将组件移动到它们各自的 JavaScript 块中,并在需要时延迟加载它们。
- 在路由级代码拆分中,您需要将每个路由的功能封装为一个单独的块。当用户浏览您的应用时,他们会提取与单个路由关联的区块,并在他们需要时获取关联的功能。
这篇博文重点介绍了在 Angular 中设置路线级拆分。
示例应用
在深入了解如何在 Angular 中使用路线级代码拆分之前,我们先来看一个示例应用:
查看应用模块的实现。在 AppModule
中定义了两个路由:与 HomeComponent
关联的默认路由和与 NyanComponent
关联的 nyan
路由:
@NgModule({
...
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
pathMatch: 'full'
},
{
path: 'nyan',
component: NyanComponent
}
])
],
...
})
export class AppModule {}
路由级代码拆分
如需设置代码拆分,需要重构 nyan
Eager 路由。
8.1.0 版本的 Angular CLI 可以使用以下命令代您完成一切工作:
ng g module nyan --module app --route nyan
这将生成:
- 一个名为 NyanModule
的新路线模块
- AppModule
中一个名为 nyan
的路线,该路线将动态加载 NyanModule
- NyanModule
中的默认路线
- 一个会在用户到达默认路线时呈现的名为 NyanComponent
的组件
下面我们手动执行这些步骤,以便更好地了解如何使用 Angular 实现代码拆分!
当用户导航到 nyan
路线时,路由器会在路由器插座中渲染 NyanComponent
。
如需在 Angular 中使用路线级代码拆分,请设置路线声明的 loadChildren
属性,并将其与动态导入相结合:
{
path: 'nyan',
loadChildren: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}
与紧急路由有两大主要区别:
- 您设置了
loadChildren
,而不是component
。使用路由级代码拆分时,您需要指向动态加载的模块,而不是组件。 - 在
loadChildren
中,当 promise 得到解析后,系统会返回NyanModule
,而不是指向NyanComponent
。
上面的代码段指定,当用户导航到 nyan
时,Angular 应从 nyan
目录动态加载 nyan.module
,并呈现与模块中声明的默认路线相关联的组件。
您可以使用此声明将默认路线与组件相关联:
import { NgModule } from '@angular/core';
import { NyanComponent } from './nyan.component';
import { RouterModule } from '@angular/router';
@NgModule({
declarations: [NyanComponent],
imports: [
RouterModule.forChild([{
path: '',
pathMatch: 'full',
component: NyanComponent
}])
]
})
export class NyanModule {}
当用户导航到 https://example.com/nyan
时,此代码会呈现 NyanComponent
。
如需检查 Angular 路由器是否在您的本地环境中延迟下载 nyan.module
,请执行以下操作:
- 按 `Control+Shift+J`(在 Mac 上,则按 `Command+Option+J`)打开开发者工具。
点击网络标签页。
点击示例应用中的 NYAN。
请注意,
nyan-nyan-module.js
文件会显示在“Network”标签页中。
在 GitHub 上查找此示例。
显示旋转图标
目前,当用户点击 NYAN 按钮时,应用并未指示它正在后台加载 JavaScript。要在加载脚本时向用户提供反馈,您可能需要添加一个旋转图标。
为此,请先在 app.component.html
的 router-outlet
元素内为指示器添加标记:
<router-outlet>
<span class="loader" *ngIf="loading"></span>
</router-outlet>
然后,添加一个 AppComponent
类来处理路由事件。此类会在收到 RouteConfigLoadStart
事件时将 loading
标志设置为 true
,并在检测到 RouteConfigLoadEnd
事件时将标志设置为 false
。
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
loading: boolean;
constructor(router: Router) {
this.loading = false;
router.events.subscribe(
(event: RouterEvent): void => {
if (event instanceof NavigationStart) {
this.loading = true;
} else if (event instanceof NavigationEnd) {
this.loading = false;
}
}
);
}
}
在下面的示例中,我们人为引入了 500 毫秒的延迟,以便您看到旋转图标的实际效果。
总结
您可以通过应用路线级代码拆分来缩减 Angular 应用的软件包大小:
- 使用 Angular CLI 延迟加载模块生成器自动生成动态加载路由的基架。
- 在用户导航到延迟路由时添加加载指示器,以显示正在进行的操作。