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


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

查看所有标签

猜你喜欢:

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

计算机组成原理

计算机组成原理

唐朔飞 / 高等教育出版社 / 2008-1 / 43.00元

《面向21世纪课程教材•普通高等教育"十一五"国家级规划教材:计算机组成原理(第2版)》内容简介:为了紧跟国际上计算机技术的新发展,《面向21世纪课程教材•普通高等教育"十一五"国家级规划教材:计算机组成原理(第2版)》对第1版各章节的内容进行了补充和修改,并增加了例题分析,以加深对各知识点的理解和掌握。《面向21世纪课程教材•普通高等教育"十一五"国家级规划教材:计算机组成原理(第2版)》通过对......一起来看看 《计算机组成原理》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换