提前预加载路由以加速用户导航。
路由级代码拆分可以通过延迟加载最初不需要的路由相关的 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
属性来配置预加载策略。