Angular 延迟加载的网络感知预加载策略 什么是预加载?预加载策略 预加载问题:网络开销 使用网络信息 API 网络信息类型 制定网络感知预加载策略 结论

2025-06-09

Angular 延迟加载的网络感知预加载策略

什么是预加载?

预加载策略

预加载问题:网络成本

使用网络信息 API

网络信息类型

制定网络感知预加载策略

结论

这篇文章解释了如何为 Angular Router 的延迟加载制定网络感知预加载策略。

无论用户的网络状况如何,它都可以通过延迟加载来改善用户体验。

什么是预加载?

预加载是 Angular Router 延迟加载的一个重要特性。该特性自 2.1.0 版本开始可用。

默认情况下,当应用程序使用延迟加载时loadChildren,分块的延迟模块将按需加载。它可以减少初始包的大小,但用户必须等待转换过程中分块的加载。

预加载改变了这一点。通过预加载,应用程序将在需要之前开始加载分块模块。它可以通过平滑过渡来提升用户体验。

这是一篇关于 Angular 预加载的最佳入门文章,作者是 Victor Savkin。他是该功能的作者。

Angular 路由器:预加载模块

预加载策略

Angular Router 支持使用PreloadingStrategy功能自定义预加载行为。有两种内置策略:PreloadAllModulesNoPreloading

NoPreloading是不预加载任何模块的默认行为。

PreloadAllModules启动后立即加载所有惰性模块。换句话说,这是一种“尽快”策略。

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

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      preloadingStrategy: PreloadAllModules, // or NoPreloading
    }),
  ],
})
class AppRoutingModule {}
Enter fullscreen mode Exit fullscreen mode

PreloadingStrategy是一个实现了方法的简单类对象preload。因此,我们可以轻松地像下面这样自定义预加载策略。

preload方法接受两个参数;routeloadroute是您在数组中声明的路由对象routesload是触发加载模块的函数。

// custom-preloading-strategy.ts
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, EMPTY } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class CustomPreloadingStrategy implements PreloadingStrategy {
  preload(route: Route, load: () => Observable<any>): Observable<any> {
    if (shouldPreload(route)) {
      return load();
    } else {
      return EMPTY;
    }
  }
}

// app-routing.module.ts
@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      preloadingStrategy: CustomPreloadingStrategy,
    }),
  ],
})
class AppRoutingModule {}
Enter fullscreen mode Exit fullscreen mode

预加载问题:网络成本

预加载可以提升用户体验,但这仅限于设备网络速度足够快的情况。有时移动设备的网络连接带宽很窄。如果应用程序试图尽快预加载所有模块,则会对其他连接(例如 AJAX)造成不良影响。

对于网络状况良好的用户来说,预加载是一个合适的解决方案。如果网络状况不佳,按需加载是更好的选择。但网络状况可能会动态变化,因此应用程序必须在运行时获取网络信息并开启/关闭预加载。

我称之为“网络感知预加载策略”。

使用网络信息 API

网络信息 API是一个新的 Web 标准 API 提案。网络信息 API 提供有关系统连接的信息。

整个 API 包含添加NetworkInformation接口以及一个添加到Navigator接口的属性:Navigator.connection。由于此 API 尚未成为标准,TypeScript 尚未提供其类型定义。因此,我将其创建为network-information-types一个包,并在以下所有示例代码中使用它。

GitHub 徽标 lacolaco /网络信息类型

网络信息 API 的类型定义

网络信息类型

不再维护

TypeScript 自 4.4 版本起原生支持网络信息 API。只需使用domworker库即可。


npm 版本

网络信息 API的类型定义

警告

这是一个临时解决方案,直到 TypeScript 将此 API 添加为内置类型支持为止。请参阅microsoft/TypeScript#27186

用法

  • 通过 npm 安装包
  • 编辑你的 tsconfig.json
  • 现在您知道navigator.connection它的类型了!

安装

$ yarn add -D network-information-types
Enter fullscreen mode Exit fullscreen mode

tsconfig.json

network-information-types修改全局类型的环境navigator类型,因此必须将其添加进去types

数组中的包名称types使用 进行解析typeRoots。默认情况下,typesRoots就是./node_modules/@types。要解析network-information-types包,请直接添加相对路径,如下所示。

{
  "compilerOptions": {
    ...
    "types": [
        "./node_modules/network-information-types"
    ]
  },
}
Enter fullscreen mode Exit fullscreen mode

使用类型

现在您可以将navigator.connection属性作为NetworkInformation对象来访问。

navigator.connection并且它的属性都是可选的,因为浏览器支持每个...

制定网络感知预加载策略

让我们使用网络信息 API 制定网络感知预加载策略!以下代码定义了shouldPreload上述示例中使用的函数CustomPreloadingStrategy

navigator.connection在有限的浏览器中无法使用。因此我们必须检测该功能。在这种情况下,

export function shouldPreload(route: Route): boolean {
  // Get NetworkInformation object
  const conn = navigator.connection;

  if (conn) {
    // With network information
  }
  return true;
}
Enter fullscreen mode Exit fullscreen mode

检测“保存数据”模式

首先,“保存数据”模式应优先考虑。这意味着用户出于成本或性能方面的考虑,非常在意有效载荷的大小。请使用NetworkInformation.saveData属性并返回false

export function shouldPreload(route: Route): boolean {
  // Get NetworkInformation object
  const conn = navigator.connection;

  if (conn) {
    // Save-Data mode
    if (conn.saveData) {
      return false;
    }
  }
  return true;
}
Enter fullscreen mode Exit fullscreen mode

检测“2G”连接

网络信息 API 可以识别网络的有效连接类型;4G、3G、2G 和慢速 2G。

在此示例中,当用户处于 2G 网络中时,应用程序会禁用预加载。

export function shouldPreload(route: Route): boolean {
  // Get NetworkInformation object
  const conn = navigator.connection;

  if (conn) {
    // Save-Data mode
    if (conn.saveData) {
      return false;
    }
    // 'slow-2g', '2g', '3g', or '4g'
    const effectiveType = conn.effectiveType || '';
    // 2G network
    if (effectiveType.includes('2g')) {
      return false;
    }
  }
  return true;
}

Enter fullscreen mode Exit fullscreen mode

网络信息 API 还包含其他一些属性,例如rttRTT(连接往返时间)。您可以为您的应用程序添加更多检查。

结论

  • Angular Router 自 2.1.0 起支持预加载功能。
  • 您可以创建自己的自定义预加载策略
  • 预加载仅对网络速度较快的用户有效。
  • 网络信息 API可在多种浏览器中使用。
  • 制定网络感知预加载策略非常容易。

感谢您的阅读!

鏂囩珷鏉ユ簮锛�https://dev.to/lacolaco/network-aware-preloading-strategy-for-angular-lazy-loading-4hae
PREV
讨论:技术面试恐怖故事
NEXT
适用于前端开发的最佳 VS Code 扩展 Javascript 代码片段 Polacode 全部自动完成 更好的注释 自动导入 - ES6、TS、JSX、TSX 自动重命名标签 括号对着色器 2 代码运行器 代码拼写检查器 ES7 React/Redux/GraphQL/React-Native 代码片段 Google 字体 实时服务器导入成本 东京之夜(主题)