Angular 延迟加载的网络感知预加载策略
什么是预加载?
预加载策略
预加载问题:网络成本
使用网络信息 API
网络信息类型
制定网络感知预加载策略
结论
这篇文章解释了如何 为 Angular Router 的延迟加载制定 网络感知预加载策略。
无论用户的网络状况如何,它都可以通过延迟加载来改善用户体验。
什么是预加载?
预加载 是 Angular Router 延迟加载的一个重要特性。该特性自 2.1.0 版本开始可用。
默认情况下,当应用程序使用延迟加载时 loadChildren
,分块的延迟模块将按需加载。它可以减少初始包的大小,但用户必须等待转换过程中分块的加载。
预加载改变了这一点。通过预加载,应用程序将 在需要之前 开始加载分块模块。它可以通过平滑过渡来提升用户体验。
这是一篇关于 Angular 预加载的最佳入门文章,作者是 Victor Savkin。他是该功能的作者。
Angular 路由器:预加载模块
预加载策略
Angular Router 支持使用 PreloadingStrategy
功能自定义预加载行为。有两种内置策略: PreloadAllModules
和 NoPreloading
。
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
方法接受两个参数; route
和 load
。 route
是您在数组中声明的路由对象 routes
。 load
是触发加载模块的函数。
// 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 提供有关系统连接的信息。
VIDEO
整个 API 包含添加 NetworkInformation
接口以及一个添加到 Navigator
接口的属性: Navigator.connection
。由于此 API 尚未成为标准,TypeScript 尚未提供其类型定义。因此,我将其创建为 network-information-types
一个包,并在以下所有示例代码中使用它。
网络信息类型
不再维护
TypeScript 自 4.4 版本起原生支持网络信息 API。只需使用 dom
或 worker
库即可。
网络信息 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 还包含其他一些属性,例如 rtt
RTT(连接往返时间)。您可以为您的应用程序添加更多检查。
结论
Angular Router 自 2.1.0 起支持 预加载 功能。
您可以创建自己的自定义预加载策略
预加载仅对网络速度较快的用户有效。
网络信息 API 可在多种浏览器中使用。
制定网络感知预加载策略非常容易。
感谢您的阅读!
鏂囩珷鏉ユ簮锛�https://dev.to/lacolaco/network-aware-preloading-strategy-for-angular-lazy-loading-4hae