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


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

查看所有标签

猜你喜欢:

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

深度学习入门

深度学习入门

[ 日] 斋藤康毅 / 陆宇杰 / 人民邮电出版社 / 2018-7 / 59.00元

本书是深度学习真正意义上的入门书,深入浅出地剖析了深度学习的原理和相关技术。书中使用Python3,尽量不依赖外部库或工具,从基本的数学知识出发,带领读者从零创建一个经典的深度学习网络,使读者在此过程中逐步理解深度学习。书中不仅介绍了深度学习和神经网络的概念、特征等基础知识,对误差反向传播法、卷积神经网络等也有深入讲解,此外还介绍了深度学习相关的实用技巧,自动驾驶、图像生成、强化学习等方面的应用,......一起来看看 《深度学习入门》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

SHA 加密
SHA 加密

SHA 加密工具

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

HEX HSV 互换工具