通过JS获取你当前的网络状况?建议大家学一学~

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心

检测网速

想要在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 {
      sinceundefined,
      online: navigator?.onLine,
      ...getConnectionProperty(),
    };
  });

  useEffect(() => {
    const onOnline = () => {
      setState((prevState) => ({
        ...prevState,
        onlinetrue,
        sincenew Date(),
      }));
    };

    const onOffline = () => {
      setState((prevState) => ({
        ...prevState,
        onlinefalse,
        sincenew 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 {
      sinceundefined,
      online: navigator?.onLine,
      ...getConnectionProperty(),
    };
  });

  useEffect(() => {
    const onOnline = () => {
      setState((prevState) => ({
        ...prevState,
        onlinetrue,
        sincenew Date(),
      }));
    };

    const onOffline = () => {
      setState((prevState) => ({
        ...prevState,
        onlinefalse,
        sincenew 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;

结语

点个【赞】和【在看】是对林三心最大的鼓励,林三心会非常开心的~~~

关注公众号【前端之神】,回复【加群】,即可获得加入【千人前端学习大群】的方式

相关推荐

  • 国内行情差,来看看国外
  • 我们真的需要把训练集的损失降到零吗?
  • 从启发式到模型化 京东推荐广告排序机制演化
  • 全平台GUI库, 物联网,嵌入式,单片机,桌面应用都行
  • 6.2K Star很精美,一个跨平台的聊天软件
  • 数据科学中10个常用的高级SQL查询方法
  • 当我们执行 npm run serve 时到底发生了什么?
  • 也看Graph CoT–大模型与知识图谱结合工作:兼看多模态大模型进展综述
  • 智猩猩AI智能体技术研讨会最终议程公布!6位学者和开发大牛现场解读AI智能体内涵
  • 神级代码注释,喜欢的拿去用
  • AI大模型,这个就叫专业!
  • 一笔漂亮的退出:回报5个亿
  • 如何促进你的职业发展?个人专著《工作的心智》,今日开始预售
  • 腾讯云披露 4 月 8 日服务故障原因;北京技术人员月平均薪酬中位值超1.2万元 | 极客头条
  • 硅谷 CEO 立「千万赌约」,邀马斯克应战:“我用 1000 万美元,赌你的 AI 预测是错的!”
  • 做代码搜索真的太难了!
  • 四年磨一剑,腾讯云亮出业内首款全自研AIGC存储解决方案
  • 量子位下一个AI选题,你说了算
  • 北大字节开辟图像生成新范式!超越Sora核心组件DiT,不再预测下一个token
  • 融合ChatGPT+DALL·E 3,贾佳亚团队新作开源畅玩:识图推理生图一站解决