Angular 网络连接状态组件

栏目: JavaScript · 发布时间: 5年前

内容简介:在开发 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 这个库来获取网络信息,有需要的小伙伴可以了解一下。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

用户中心设计

用户中心设计

(美国)弗登伯格等编 / 高等教育出版社 / 2003-8 / 20.00元

本书以用户对最终产品或系统的所见及所感为出发点考虑设计方法,所涉及的产品从数据库软件到语音识别软件,在众多项目(医疗保健、金融证券、航空事业、保险业、汽车制造业及零售业等)中得到验证。内容包括:能带来突破性增益的针对UCD的完整的周期化方法;现有产品评测、机构评定以使其适用UCD方法;提高用户感知舒适度;在外延型/内适型应用环境下的软件设计、硬件设计、网站建设和服务中应用UCD;当前UCD优化及未......一起来看看 《用户中心设计》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具