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


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

查看所有标签

猜你喜欢:

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

趋势红利

趋势红利

刘润 / 文化发展出版社(原印刷工业出版社) / 2016-6-1 / 45.00

【编辑推荐】 1、国内顶尖的互联网转型专家,海尔、百度等知名企业战略顾问刘润送给传统企业的转型、创新“导航仪”,这个时代企业家的必修课 站在近200年商业全景图角度,刘润发现三种企业类型(产品型、渠道型、营销型),针对不同企业类型定制转型战略(找到自己的未来红利),方便 传统企业对号入座:不走错路就是节省时间,适合自己的最有效率。 本书内容还源自芬尼克兹、红领集团、名创优品、必要......一起来看看 《趋势红利》 这本书的介绍吧!

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

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具