前端网络监测
介绍
前端监测可谓也是大有学问的,一般有网络监测、页面加载监控、错误监测、用户行为分析等。今天看看网络监测,前端网络监测是网站性能和用户体验管理的重要手段之一,对于保障网站的正常运行、提升用户体验和满意度具有重要的价值和意义。
例如,当用户网络状态不太好的时候,可以给用户提供较模糊的图片,这样用户还能看见一点点东西。又或者当用户在用着用着,突然网页不好用啦。还以为系统出问题了。但有可能是断网了。这个时候就可以提示用户,有一个好的体验。又或者当用户网络状态很好的情况下,可以去预加载一些资源。
监测获取网络状态
从上面,我们需要知道用户的网络状态,那我们怎样知道用户的网络状态呢。
那就用到浏览器的一些api啦。也就是navigator.connection
。
navigator.connection 是一个 Web API 对象,用于提供有关设备当前网络连接状况的信息,包括网络类型、带宽、延迟和数据使用量等。该对象基于 W3C 的 Network Information API 标准开发,被大部分主流浏览器广泛支持。
navigator.connection.effectiveType
当前网络连接的有效类型,即设备可以实际使用的网络速度类型。例如,在 4G 网络下,该属性可能为 4g,而在 3G 网络下则可能为 3g。
wifi也是4g
navigator.connection.downlink
navigator.connection.downlink:当前网络连接的下行带宽估计值(以 Mbps 为单位)。也就是宽带啦。
navigator.connection.rtt
当前网络连接的往返时延(RTT)估计值(以毫秒为单位)。也就是延迟。
navigator.connection.saveData
一个布尔值,表示用户设备是否启用了数据节约模式。
有了这些api之后,我们就可以获取到网络状态了,但是怎么监听呢,用setInterval定时或者requestAnimationFrame? 当然不用。还有专门为了监听它的一个方法。
这个时候,已经可以通过上面几个api来判断当前的网络状态。但是对于离线和在线还没有明确的来判断,好在navigator也提供了api,navigator.onLine,即可判断是否在线。
监听网络
const watchNet = () => {
const { effectiveType, downlink, rtt } = (navigator as any).connection;
const netInfo = {
effectiveType,
downlink,
rtt,
};
if (navigator.onLine) {
netInfo.type = '在线';
} else {
netInfo.type = '离线';
}
};
window.addEventListener('online', watchNet)
window.addEventListener('offline', watchNet)
navigator.connection.addEventListener('change', watchNet);
通过上面三个js监听,即可监听到网络的变化和在线、离线。
组件源码
import React, { useEffect, useState, type FC } from 'react';
import './index.less';
type StatusType = 'primary' | 'success' | 'warning' | 'danger';
type opacityType = 'lower' | 'low' | 'high' | 'higer';
const Wnet: FC<{ bgType?: StatusType; opcType?: opacityType }> = (props: {
bgType?: StatusType;
opcType?: opacityType;
}) => {
const { bgType = 'primary', opcType = 'higer' } = props;
const [netInfo, setNetInfo] = useState({
type: '在线',
rtt: 0,
downlink: 0,
});
const theme: Record<StatusType, string> = {
primary: 'wnet-primary',
success: 'wnet-success',
warning: 'wnet-warning',
danger: 'wnet-danger',
};
const bgopacity: Record<opacityType, string> = {
lower: '-opacityLower',
low: '-opacityLow',
high: '-opacityHigh',
higer: '-opacityHiger',
};
const watchNet = () => {
const { effectiveType, downlink, rtt } = (navigator as any).connection;
const netInfo: any = {
effectiveType,
downlink,
rtt,
};
if (navigator.onLine) {
netInfo.type = '在线';
} else {
netInfo.type = '离线';
}
setNetInfo(netInfo);
};
useEffect(() => {
window.addEventListener('online', watchNet);
window.addEventListener('offline', watchNet);
const navigation = (navigator as any).connection;
navigation.addEventListener('change', watchNet);
}, []);
return (
<div
className={`wnet ${
netInfo.type === '离线'
? theme['danger'] + bgopacity[opcType]
: theme[bgType] + bgopacity[opcType]
}`}
>
<div>
<strong>网络状态:</strong>
<span>{netInfo.type}</span>
</div>
<div>
<strong>延迟:</strong>
<span>{netInfo.rtt}ms</span>
</div>
<div>
<strong>宽带:</strong>
<span>{netInfo.downlink}Mb/s</span>
</div>
</div>
);
};
export default Wnet;