在 Angular 中路由预加载策略

提前预加载路由,以加快用户的访问速度导航。

路由级代码拆分可延迟与最初并不需要的路由相关联的 JavaScript,从而帮助您缩短应用的初始加载时间。这样,Angular 路由器就会等到用户导航到指定路线后再触发网络请求以下载关联的 JavaScript。

虽然这种方法非常适合初始网页加载,但可能会减慢浏览速度,具体取决于用户的网络延迟和带宽。解决此问题的一种方法是路由预加载。通过预加载,当用户位于给定路线时,您可以下载并缓存与接下来可能需要的路线相关联的 JavaScript。Angular 路由器开箱即用此功能。

在这篇博文中,您将了解如何利用 Angular 中的 JavaScript 预加载功能,在使用路线级代码拆分时加快导航速度。

Angular 中的路由预加载策略

Angular 路由器提供了一个名为 preloadingStrategy 的配置属性,该属性定义了预加载和处理延迟加载的 Angular 模块的逻辑。我们将介绍两种可能的策略:

  • PreloadAllModules:顾名思义,会预加载所有延迟加载的路由
  • QuicklinkStrategy:仅预加载与当前页面上的链接关联的路由。

本文的其余部分将介绍一个示例 Angular 应用。您可以在 GitHub 上找到源代码。

使用 PreloadAllModules 策略

示例应用有多个延迟加载的路由。如需使用 Angular 内置的 PreloadAllModules 策略预加载所有这些属性,请在路由器配置中将其指定为 preloadingStrategy 属性的值:

import { RouterModule, PreloadAllModules } from '@angular/router';
// …

RouterModule.forRoot([
  …
], {
  preloadingStrategy: PreloadAllModules
})
// …

现在,提供应用并查看 Chrome 开发者工具中的 Network 面板:

  1. 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
  2. 点击网络标签页。

打开应用时,您应该会看到路由器在后台下载了 nyan-nyan-module.jsabout-about-module.js

PreloadAllModules 策略的实际运用。

路由器还注册了模块的路线声明,以便在您导航到与任何预加载模块关联的网址时,可以立即进行转换。

PreloadAllModules 在很多情况下都很有用。但是,当您有数十个模块时,激进的预加载会切实增加网络使用量。此外,由于路由器需要在所有预加载模块中注册路由,因此可能会导致界面线程中的计算密集型,并导致用户体验缓慢。

quicklink 库可为大型应用提供更好的策略。它使用 IntersectionObserver API 仅预加载与网页上当前可见的链接相关联的模块。

您可以使用 ngx-quicklink 软件包添加指向 Angular 应用的快捷链接。首先,从 npm 安装软件包:

npm install --save ngx-quicklink

一旦它在您的项目中可用,您就可以指定路由器的 preloadingStrategy 并导入 QuicklinkModule 来使用 QuicklinkStrategy

import {QuicklinkStrategy, QuicklinkModule} from 'ngx-quicklink';
…

@NgModule({
  …
  imports: [
    …
    QuicklinkModule,
    RouterModule.forRoot([…], {
      preloadingStrategy: QuicklinkStrategy
    })
  ],
  …
})
export class AppModule {}

现在,当您再次打开该应用时,您会发现路由器仅预加载 nyan-nyan-module.js,因为页面中央的按钮有一个指向它的路由器链接。打开侧边导航栏时,您会发现路由器预加载了“关于”路线:

快速链接预加载策略演示。

以上示例适用于基本应用,但如果您的应用包含多个延迟加载模块,则您需要将 QuicklinkModule 导入共享模块,将其导出,然后将共享模块导入延迟加载模块。

首先,将 QuicklinkModulengx-quicklink 导入共享模块并将其导出:

import { QuicklinkModule } from 'ngx-quicklink';
…

@NgModule({
  …
  imports: [
    QuicklinkModule
  ],
  exports: [
    QuicklinkModule
  ],
  …
})
export class SharedModule {}

然后,将 SharedModule 导入所有延迟加载的模块:

import { SharedModule } from '@app/shared/shared.module';
…

@NgModule({
  …
  imports: [
      SharedModule
  ],
  …
});

现在,您的延迟加载模块中将提供 Quicklinks

不局限于基本的预加载

虽然通过快捷链接选择性预加载可以显著加快导航速度,但您可以利用预测性预加载(由 Guess.js 实现)提高预加载策略的广告联盟效率。通过分析来自 Google Analytics 或其他分析服务提供商的报告,Guess.js 可以预测用户的导航历程,并仅预加载接下来可能需要的 JavaScript 代码块。

如需了解如何将 Guess.js 与 Angular 结合使用,请参阅 Guess.js 网站上的此页面

总结

如需在使用路线级代码拆分时加快导航速度,请执行以下操作:

  1. 根据应用的大小选择合适的预加载策略:
    • 模块很少的应用可以使用 Angular 的内置 PreloadAllModules 策略。
    • 包含许多模块的应用应使用自定义预加载策略(例如 Angular 的快捷链接)或预测性预加载(如 Guess.js 中所实现的那样)。
  2. 通过设置 Angular 路由器的 preloadStrategy 属性来配置预加载策略。