使用路由级代码分块来提升应用性能!
本文介绍了如何在 Angular 应用中设置路径级代码拆分,这可以缩减 JavaScript 软件包的大小,并显著缩短有交互的时间。
您可以在 GitHub 上找到本文中的代码示例。eager 分支中提供了 eager 路由示例。路由级代码拆分示例位于“lazy”分支中。
代码分块的重要性
随着 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
提前路由。
8.1.0 版 Angular CLI 可以通过以下命令为您完成所有操作:
ng g module nyan --module app --route nyan
这将生成:
- 一个名为 NyanModule
的新路由模块
- 一个名为 nyan
的 AppModule
中的路由,用于动态加载 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`)打开 DevTools。
点击网络标签页。
在示例应用中点击 NYAN。
请注意,
nyan-nyan-module.js
文件会显示在“网络”标签页中。
在 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 延迟加载模块生成器自动搭建动态加载的路由。
- 在用户导航到延迟路线时添加加载指示器,以显示正在执行的操作。