Angular 网络连接状态组件
栏目: JavaScript · 发布时间: 6年前
内容简介:在开发 Web 应用程序时,有时候我们需要获取当前的网络状态,然后根据不同的网络状态显示不同的提示消息或显示不同页面内容。对于原生应用、混合应用或提供 JS-SDK 的第三方平台来说,我们可以通过相关的 Network API 来获取当前的网络连接状态。但对于 Web 应用来说,虽然也有相关的此 API 是由下面是网络连接类型的评估标准:
在开发 Web 应用程序时,有时候我们需要获取当前的网络状态,然后根据不同的网络状态显示不同的提示消息或显示不同页面内容。对于原生应用、混合应用或提供 JS-SDK 的第三方平台来说,我们可以通过相关的 Network API 来获取当前的网络连接状态。但对于 Web 应用来说,虽然也有相关的 Network Information API ,但兼容性并不是太好,具体的兼容情况,可以参考 Can I Use - netinfo 。
Network Information API
此 API 是由 WICG
编辑的草案,目前可在 Chrome 61+ 的版本中使用。开发者可以通过 navigator.connection
对象来访问与当前网络连接相关的属性:
- connection.type:返回当前 User Agent 的物理网络类型,可能的值为 “cellular”,”ethernet”,”wfi” 或 “none” 等;
- connection.downlink:返回基于最近观察到的活动连接的有效带宽(以 Mb/s 为单位);
- connection.rtt:返回基于最近观察到的活动连接估计平均往返时间(以毫秒为单位);
- connection.saveData:如果用户在其浏览器启用 “reduced data mode” 模式,则返回 true;
- connection.effectiveType:返回有效的网络连接类型,可能的值为 slow-2g,2g,3g 或 4g。该值的是基于 rtt 和 downlink 的值测算出来的。
下面是网络连接类型的评估标准:
CT | Minimum RTT (ms) | Maximum downlink (Kbps) | Explanation |
---|---|---|---|
slow-2g | 2000 | 50 | The network is suited for small transfers only such as text-only pages. |
2g | 1400 | 70 | The network is suited for transfers of small images. |
3g | 270 | 700 | The network is suited for transfers of large assets such as high resolution images, audio, and SD video. |
4g | 0 | ∞ | The network is suited for HD video, real-time video, etc. |
讲到这里突然想起之前看到的一篇文章 JS 检测网络带宽 ,有兴趣的小伙伴可以了解一下。
开发网络连接组件
通过结合 Network Information API 与 Angular,我们可以创建一个组件,实现根据不同网络连接速度渲染不同的内容。比如,当我们检测到弱网络的时候,我们可以渲染一个占位符或一个低分辨率的图片或视频,从而提高页面的加载速度。
首先,让我们把连接变化事件封装为一个 Observable 对象:
const connection$ = new Observable((observer) => { const { effectiveType } = navigator.connection; observer.next(effectiveType); const onConnectionChange = () => { const { effectiveType } = navigator.connection; observer.next(effectiveType); } navigator.connection.addEventListener('change', onConnectionChange) return () => { navigator.connection.removeEventListener('change', onConnectionChange); observer.complete(); } });
在页面初始化和连接网络状态发生变化的时候,可观察的 connection$ 对象将会自动通知我们当前的网络连接状态。
接下来,我们来创建 ConnectionComponent 组件和相关的 Connection 指令:
connection.component.ts
@Component({ selector: 'connection', template: ` <ng-template [ngTemplateOutlet]="fast.tpl" *ngIf="isFast"></ng-template> <ng-template [ngTemplateOutlet]="slow.tpl" *ngIf="!isFast"></ng-template> `, }) export class ConnectionComponent { isFast = true; @ContentChild(FastDirective) fast: FastDirective; @ContentChild(SlowDirective) slow: SlowDirective; private subscription: Subscription; ngOnInit() { const connection = navigator.connection; if (!connection) { // if the browser doesn't support it, we render the fast template return; } this.subscription = connection$ .subscribe((effectiveType: string) => { if (/slow-2g|2g|3g/.test(effectiveType)) { this.isFast = false; } else { this.isFast = true; } }) } ngOnDestroy() { this.subscription && this.subscription.unsubscribe(); } }
fast.directive.ts
@Directive({ selector: '[fast]' }) export class FastDirective { constructor(public tpl: TemplateRef<any>) { } }
slow.directive.ts
@Directive({ selector: '[slow]' }) export class SlowDirective { constructor(public tpl: TemplateRef<any>) { } }
在上面的示例中,ConnectionComponent 会根据 effectiveType
属性的值,然后显示 slow 或 fast 指令实例所关联的模板。现在我们来看一下如何使用:
<connection> <ng-container *fast> Fast connection - Render a video </ng-container> <ng-container *slow> Slow connection - Render a placeholder </ng-container> </connection>
正如前面提到的,基于 Network Information API ,我们也可以实现一个简单的指令,根据不同的网络状态显示不同分辨率的图片。
<img connection slowSrc="https://via.placeholder.com/350x150?text=slow" fastSrc="https://via.placeholder.com/350x150?text=fast">
对应的 connection 指令的具体实现如下:
import { Directive, Attribute, ElementRef } from '@angular/core'; @Directive({ selector: '[connection]' }) export class ConnectionDirective { constructor(@Attribute('slowSrc') private slowSrc, @Attribute('fastSrc') private fastSrc, private host: ElementRef<HTMLImageElement> ) { } ngOnInit() { const { effectiveType } = navigator.connection; let src; if (/slow-2g|2g|3g/.test(effectiveType)) { src = this.slowSrc; } else { src = this.fastSrc; } this.host.nativeElement.setAttribute('src', src) } }
查看线上完整的示例: Stackblitz
总结
本文是在过完 “10·24 — 爱码士” 节后,参考 connection-aware-components-in-angular 这篇文章整理的。其中主要介绍了 Network Information API 涉及的相关属性及每个属性的作用。对于使用 Ionic 或 Cordova 项目来说,可以使用 cordova-plugin-network-information 这个库来获取网络信息,有需要的小伙伴可以了解一下。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- React 组件模式-有状态组件 x 无状态组件、容器组件 x 展示组件、高阶组件 x 渲染回调(函数作为子组件)
- Vue异步组件处理路由组件加载状态
- 为管理复杂组件状态困扰?试试 vue 简单状态管理 Store 模式
- 悟空活动中台:微组件状态管理(上)
- 悟空活动中台:微组件状态管理(上)
- React组件设计实践总结05 - 状态管理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。