Angular懒加载路由使用方法
简介 延迟加载是一种优化策略,只加载用户当前真正需要的模块。这一方法能够显著提升应用性能,同时减小初始打包体积——在大型项目中效果尤为突出。 默认情况下,Angular 采用“急切加载”模式,即在应用启动前加载所有模块。对于许多场景而言,这种方式并无问题,但当模块数量增加时,加载时间会形成性能瓶颈。
简介
延迟加载是一种优化策略,只加载用户当前真正需要的模块。这一方法能够显著提升应用性能,同时减小初始打包体积——在大型项目中效果尤为突出。

默认情况下,Angular 采用“急切加载”模式,即在应用启动前加载所有模块。对于许多场景而言,这种方式并无问题,但当模块数量增加时,加载时间会形成性能瓶颈。实际上,这是不少开发者容易忽略的优化环节。
接下来,将逐步在 Angular 应用中实现懒加载路由。
先决条件
要完成本教程,需要满足以下条件:
- 本地安装 Node.js(具体步骤可参考《如何安装 Node.js 并创建本地开发环境》)。
- 了解 Angular 项目的基本搭建方法。
本教程在 Node v16.4.0、npm v7.19.0、@angular/core v12.1.0 和 @angular/router v12.1.0 环境下验证通过。
步骤 1 – 设置项目
懒加载的路由不能放置在根应用模块中,而应放在独立的功能模块中。这是基本的设计原则。
首先,通过 Angular CLI 创建一个带路由的新项目:
ng new angular-lazy-loading-example --routing --style=css --skip-tests
然后进入项目目录:
cd angular-lazy-loading-example
接下来创建一个新的功能模块:
ng generate module shop --route shop --module app.module
在 shop 功能模块中,需要创建三个组件:
第一个是购物车组件:
ng generate component shop/cart
第二个是结算组件:
ng generate component shop/checkout
第三个是确认组件:
ng generate component shop/confirm
这三个组件将位于 shop 目录下。至此,项目已准备好包含 3 个组件的 shop 模块。
步骤 2 – 使用 loadChildren
在主路由配置中,关键代码如下所示:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: 'shop', loadChildren: () => import('./shop/shop.module').then(m => m.ShopModule) },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
从 Angular 8 开始,loadChildren 接受一个函数,该函数使用动态导入语法来加载模块。只有在实际访问该路由时,才会触发动态导入。动态导入基于 Promise,获取模块后可以调用其类。
步骤 3 – 在功能模块中设置路由配置
最后一步是配置功能模块自身的路由。
示例代码如下:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CartComponent } from './cart/cart.component';
import { CheckoutComponent } from './checkout/checkout.component';
import { ConfirmComponent } from './confirm/confirm.component';
const routes: Routes = [
{ path: '', component: CartComponent },
{ path: 'checkout', component: CheckoutComponent },
{ path: 'confirm', component: ConfirmComponent },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ShopRoutingModule { }
最后,在功能模块本身中引入路由时,需要使用 RouterModule.forChild 而非 forRoot:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ShopRoutingModule } from './shop-routing.module';
import { ShopComponent } from './shop.component';
import { CartComponent } from './cart/cart.component';
import { CheckoutComponent } from './checkout/checkout.component';
import { ConfirmComponent } from './confirm/confirm.component';
@NgModule({
declarations: [
ShopComponent,
CartComponent,
CheckoutComponent,
ConfirmComponent,
],
imports: [
CommonModule,
ShopRoutingModule
]
})
export class ShopModule { }
现在,可以使用 routerLink 指令导航到 /shop、/shop/checkout 或 /shop/confirm。只有当首次访问这些路径时,对应的模块才会被加载。
在终端启动开发服务器:
ng serve
此时可以看到生成的打包文件:一个 main.js 以及独立的懒加载文件 src_app_shop_shop_module_ts.js:
初始块文件 | 名称 | 大小
vendor.js | vendor | 2.38 MB
polyfills.js | polyfills | 128.58 kB
main.js | main | 57.18 kB
runtime.js | runtime | 12.55 kB
styles.css | styles | 119 字节
| 初始总计 | 2.58 MB
延迟块文件 | 名称 | 大小
src_app_shop_shop_module_ts.js | - | 10.62 kB
在浏览器中访问 localhost:4200,打开开发者工具的网络面板进行验证:初始加载时不会出现懒加载块;当导航到 /shop 时,src_app_shop_shop_module_ts.js 会出现在网络请求中。恭喜,应用已成功支持懒加载。
结论
本文从项目创建到模块拆分,再到动态加载,完整演示了在 Angular 应用中配置懒加载路由的流程。每一步都清晰明确。
接下来可以进一步学习如何测试带有依赖的组件、测试服务,以及使用模拟(mock)、存根(stub)和间谍(spy)等测试技巧。
官方文档提供了更详细的说明,其中还包含懒加载的高级用法。建议查阅以获取更多信息。
