网站首页 > 技术文章 正文
检测网速
想要在Web端检测网速,其实很简单,有一个全局的对象——navigation,我们来看看它的身上都有哪些东西:
属性 | 描述 | 类型 |
downlink | 有效带宽估算(单位:兆比特/秒) | number |
effectiveType | effectiveType | slow-2g/2g/3g/4g |
rtt | 当前连接下评估的往返时延 | number |
saveData | 用户代理是否设置了减少数据使用的选项 | boolean |
useNetwork
我们可以自定义一个hook,用来获取网页当前的网络状态~需要具备以下要素:
- 1、返回的数据所需的ts类、监听网络变化的enum
- 2、获取网络状态
- 3、监听网络变化,并实时更新最新的网络状态
第一步:所需的ts类型
说说NetworkState的各个参数:
- since:记录当时检测的时间
- oline:记录是否有网络
- rtt:记录时延
- downlink:记录带宽
- saveData:记录用户代理是否设置了减少数据使用
- effectiveType:网络连接类型
// hook返回的值
interface NetworkState {
since?: Date;
online?: boolean;
rtt?: number;
downlink?: number;
saveData?: boolean;
effectiveType?: string;
}
// 监听网络变化的事件名enum
enum NetworkEventType {
ONLINE = 'online',
OFFLINE = 'offline',
CHANGE = 'change',
}
第二步:获取网络状态
function getConnection() {
const nav = navigator as any;
if (typeof nav !== 'object') return null;
return nav.connection || nav.mozConnection || nav.webkitConnection;
}
function getConnectionProperty(): NetworkState {
const c = getConnection();
if (!c) return {};
return {
rtt: c.rtt,
saveData: c.saveData,
downlink: c.downlink,
effectiveType: c.effectiveType,
};
}
第三步:实时更新网络状态
unction useNetwork(): NetworkState {
const [state, setState] = useState(() => {
return {
since: undefined,
online: navigator?.onLine,
...getConnectionProperty(),
};
});
useEffect(() => {
const onOnline = () => {
setState((prevState) => ({
...prevState,
online: true,
since: new Date(),
}));
};
const onOffline = () => {
setState((prevState) => ({
...prevState,
online: false,
since: new Date(),
}));
};
const onConnectionChange = () => {
setState((prevState) => ({
...prevState,
...getConnectionProperty(),
}));
};
window.addEventListener(NetworkEventType.ONLINE, onOnline);
window.addEventListener(NetworkEventType.OFFLINE, onOffline);
const connection = getConnection();
connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange);
return () => {
window.removeEventListener(NetworkEventType.ONLINE, onOnline);
window.removeEventListener(NetworkEventType.OFFLINE, onOffline);
connection?.removeEventListener(NetworkEventType.CHANGE, onConnectionChange);
};
}, []);
return state;
}
完整代码
import { useEffect, useState } from 'react';
export interface NetworkState {
since?: Date;
online?: boolean;
rtt?: number;
downlink?: number;
saveData?: boolean;
effectiveType?: string;
}
enum NetworkEventType {
ONLINE = 'online',
OFFLINE = 'offline',
CHANGE = 'change',
}
function getConnection() {
const nav = navigator as any;
if (typeof nav !== 'object') return null;
return nav.connection || nav.mozConnection || nav.webkitConnection;
}
function getConnectionProperty(): NetworkState {
const c = getConnection();
if (!c) return {};
return {
rtt: c.rtt,
saveData: c.saveData,
downlink: c.downlink,
effectiveType: c.effectiveType,
};
}
function useNetwork(): NetworkState {
const [state, setState] = useState(() => {
return {
since: undefined,
online: navigator?.onLine,
...getConnectionProperty(),
};
});
useEffect(() => {
const onOnline = () => {
setState((prevState) => ({
...prevState,
online: true,
since: new Date(),
}));
};
const onOffline = () => {
setState((prevState) => ({
...prevState,
online: false,
since: new Date(),
}));
};
const onConnectionChange = () => {
setState((prevState) => ({
...prevState,
...getConnectionProperty(),
}));
};
window.addEventListener(NetworkEventType.ONLINE, onOnline);
window.addEventListener(NetworkEventType.OFFLINE, onOffline);
const connection = getConnection();
connection?.addEventListener(NetworkEventType.CHANGE, onConnectionChange);
return () => {
window.removeEventListener(NetworkEventType.ONLINE, onOnline);
window.removeEventListener(NetworkEventType.OFFLINE, onOffline);
connection?.removeEventListener(NetworkEventType.CHANGE, onConnectionChange);
};
}, []);
return state;
}
export default useNetwork;
- 上一篇: JavaScript 事件循环机制详解
- 下一篇: p5.js 圆弧的用法
猜你喜欢
- 2025-08-01 装饰材料——JS防水涂料,施工必知!
- 2025-08-01 p5.js 圆弧的用法
- 2025-08-01 JavaScript 事件循环机制详解
- 2025-05-09 js防水涂料的使用方法(js防水涂料的防水作用机理)
- 2025-05-09 JavaScript 展开data 是什么语法(js实现展开收缩)
- 2025-05-09 JavaScript 可选链操作符详解(javascript选项)
- 2025-05-09 Express.js 创建Node.js Web应用(express搭建)
- 2025-05-09 JavaScript 强制回流问题及优化方案
- 2025-05-09 OS.js – 开源的 Web OS 系统,赶快来体验
- 2025-05-09 祝各位节(圆周率日)快乐(国际数学节国际圆周率日)
- 08-03MySQL数据库的预处理详解
- 08-03《阿常·MySQL 70讲》全套教学视频
- 08-03隐式等待、显示等待和强制等待
- 08-03零基础C#上位机框架项目实例(完结篇)
- 08-03一文搞懂构建Web内容的技术
- 08-03西门子WINCC中的VBScript(VBS)常用于自动化脚本开发
- 08-03力控和sql2000之间的数据转储
- 08-03组态王|通过日历控件选择时间段查询历史报警
- 1521℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 624℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 527℃MySQL service启动脚本浅析(r12笔记第59天)
- 492℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 492℃启用MySQL查询缓存(mysql8.0查询缓存)
- 479℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 461℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 458℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- htmlbackground-image (68)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)