提前预加载路由以加速用户导航。
路由级代码拆分可以通过延迟加载最初不需要的路由相关的 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 DevTools 中的“网络”面板
- 按
Control+Shift+J(或 Mac 上的Command+Option+J) 打开 DevTools。 - 点击“网络”选项卡。
您应该看到,当您打开应用程序时,路由器在后台下载了 nyan-nyan-module.js 和 about-about-module.js
路由器还注册了模块的路由声明,以便当您导航到与任何预加载模块关联的 URL 时,转换是瞬间完成的。
使用 Quicklink 预加载策略
PreloadAllModules 在很多情况下都很有用。 但是,当您有数十个模块时,其激进的预加载可能会真正增加网络使用量。 此外,由于路由器需要注册所有预加载模块中的路由,因此可能会导致 UI 线程中的密集计算,并导致用户体验缓慢。
quicklink 库为大型应用提供了更好的策略。 它使用 IntersectionObserver API 仅预加载与当前页面上可见的链接关联的模块。
您可以使用 ngx-quicklink 包将 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,因为页面中心的按钮有一个指向它的路由器链接。 当您打开侧边导航时,您会注意到路由器随后预加载了“About”路由
在多个延迟加载的模块中使用 Quicklink 预加载策略
上面的示例适用于基本应用程序,但如果您的应用程序包含多个延迟加载的模块,您将需要将 QuicklinkModule 导入到共享模块中,导出它,然后将共享模块导入到您的延迟加载模块中。
首先将 QuicklinkModule 从 ngx-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 现在将在您的延迟加载模块中可用。
超越基本预加载
虽然通过 quicklink 进行选择性预加载可以显着加快导航速度,但您可以通过使用预测性预加载(由 Guess.js 实现)使您的预加载策略在网络上更高效。 通过分析来自 Google Analytics 或其他分析提供商的报告,Guess.js 可以预测用户的导航旅程,并且仅预加载接下来可能需要的 JavaScript 代码块。
您可以在 Guess.js 站点的此页面上了解如何将 Guess.js 与 Angular 一起使用。
结论
为了在使用路由级代码拆分时加快导航速度
- 根据应用程序的大小选择合适的预加载策略
- 模块较少的应用程序可以使用 Angular 的内置
PreloadAllModules策略。 - 具有许多模块的应用程序应使用自定义预加载策略,例如 Angular 的 quicklink,或预测性预加载,如 Guess.js 中实现的那样。
- 模块较少的应用程序可以使用 Angular 的内置
- 通过设置 Angular 路由器的
preloadStrategy属性来配置预加载策略。