Angular 中的路由级代码拆分

使用路由级代码分块来提升应用性能!

本文介绍了如何在 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 的新路由模块 - 一个名为 nyanAppModule 中的路由,用于动态加载 NyanModule - NyanModule 中的默认路由 - 一个名为 NyanComponent 的组件,将在用户命中默认路由时呈现

我们来手动完成这些步骤,以便更好地了解如何使用 Angular 实现代码分块!

当用户导航到 nyan 路由时,路由器将在路由器插座中呈现 NyanComponent

如需在 Angular 中使用路由级代码拆分,请设置路由声明的 loadChildren 属性,并将其与动态导入结合使用:

{
  path
: 'nyan',
  loadChildren
: () => import('./nyan/nyan.module').then(m => m.NyanModule)
}

与提前路由相比,有两个关键区别:

  1. 您设置的是 loadChildren,而不是 component。使用路由级代码拆分时,您需要指向动态加载的模块,而不是组件。
  2. 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,请执行以下操作:

  1. 按 `Control+Shift+J`(在 Mac 上为 `Command+Option+J`)打开 DevTools。
  2. 点击网络标签页。

  3. 在示例应用中点击 NYAN

  4. 请注意,nyan-nyan-module.js 文件会显示在“网络”标签页中。

使用路径级代码拆分延迟加载 JavaScript 软件包

GitHub 上找到此示例。

显示旋转图标

目前,当用户点击 NYAN 按钮时,应用不会指明它正在后台加载 JavaScript。为了在加载脚本时向用户提供反馈,您可能需要添加一个旋转图标。

为此,请先在 app.component.htmlrouter-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 应用的软件包大小:

  1. 使用 Angular CLI 延迟加载的模块生成器自动搭建动态加载的路由。
  2. 在用户导航到延迟路线时添加加载指示器,以显示正在执行的操作。