如何用JavaScipt测网速


Posted in Javascript onMay 09, 2021

前言

事情是这样的,最近尝试写一个通过判断当前网速,从而在前端控制范围请求去分步请求一个大型文件的库。这个东东我现在一行代码都还没写,除了突然发现这个需求的思路有些不太实际之外,另一个原因是我突然问自己——前端要怎么判断网速啊?? ? !

前端判断网速的原理总结

(注:下面求的网速单位默认为KB/S)通过查阅相关资料,我发现思路主要是分为以下几种:

1.通过img加载或者发起Ajax请求计算网速

通过请求一个和服务端同域的文件,例如图片等,在前端开始请求和收到响应两个时间点分别通过Date.now标记start和end,因为Date.now得出的是1970年1月1日(UTC)到当前时间经过的毫秒数,所以我们通过end - start求出时间差(ms),然后通过计算:

文件大小(KB) * 1000 /( end -start )

就可以计算出网速了(KB/S)。

而请求文件又有两种方法:通过img加载或者AJAX加载:

  • 通过创建img对象,设置onload监听回调,然后指定src, 一旦指定src,图片资源就会加载,完成时onload回调就会调用,我们可以根据时机分别标记start和end。
  • 通过AJAX进行请求,即创建XHR对象,在onreadystatechange回调里,判断当readystate = 4时候加载完成,根据时机分别标记start和end。

2.window.navigator.connection.downlink网速查询

我们还可以通过一些H5的先进API去实现,例如这里我们可以使用的是window.navigator.connection.downlink 去查询,但是正如你所知道的是,这类API都是一副德性,即老生常谈的兼容性问题,所以我们一般都是作为一种预备的手段,通过能力检测,能用就用它,不能用就通过别的方法。而且需要注意downlink的单位是mbps,转化成KB/S的公式是

navigator.connection.downlink * 1024 / 8

乘1024可以理解,为什么后面要除8呢?这是因为mbps里的b指的是bit(比特),KB/s里面的B指的是Byte(字节),1字节(b)=8比特(bit),所以需要除个8

3. 一般来说,通过请求文件测算网速

单次可能会有误差,所以我们可以请求多次并计算均值。

前端判断网速的方法及其优缺点

  • img加载测速:借助img对象加载测算网速。优点:没有跨域带来的问题。缺点:(1)要自己测文件大小并提供参数fileSize,(2)文件必须为图片 (3)文件大小不能灵活控制
  • Ajax测速: 通过Ajax测算网速。 优点: (1)不用提供文件大小参数,因为可以从response首部获得(2)测试的文件不一定要是图片,且数据量能灵活控制。缺点:跨域问题
  • downlink测速: 通过navigator.connection.downlink读取网速。优点:不需要任何参数。缺点:1.兼容性很有问题,2.带宽查询不是实时的,具有分钟级别的时间间隔
  • 综合实现:先尝试采用downlink测速,否则多次AJAX测速并求平均值

img加载测速

function getSpeedWithImg(imgUrl, fileSize) {
    return new Promise((resolve, reject) => {
        let start = null;
        let end = null;
        let img = document.createElement('img');
        start = new Date().getTime();
        img.onload = function (e) {
            end = new Date().getTime();
            const speed = fileSize * 1000 / (end - start)
            resolve(speed);
        }
        img.src = imgUrl;
    }).catch(err => { throw err });
}

Ajax测速

function getSpeedWithAjax(url) {
    return new Promise((resolve, reject) => {
        let start = null;
        let end = null;
        start = new Date().getTime();
        const xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                end = new Date().getTime();
                const size = xhr.getResponseHeader('Content-Length') / 1024;
                const speed = size * 1000 / (end - start)
                resolve(speed);
            }
        }
        xhr.open('GET', url);
        xhr.send();
    }).catch(err => { throw err });
}

downlink测速

function getSpeedWithDnlink() {
    // downlink测算网速
    const connection = window.navigator.connection;
    if (connection && connection.downlink) {
        return connection.downlink * 1024 / 8;
    }
}

综合测速

function getNetSpeed(url, times) {
    // downlink测算网速
    const connection = window.navigator.connection;
    if (connection && connection.downlink) {
        return connection.downlink * 1024 / 8;
    }
    // 多次测速求平均值
    const arr = [];
    for (let i = 0; i < times; i++) {
        arr.push(getSpeedWithAjax(url));
    }
    return Promise.all(arr).then(speeds => {
        let sum = 0;
        speeds.forEach(speed => {
            sum += speed;
        });
        return sum / times;
    })
}

以上代码我发了一个npm包,可以通过下载

npm i network-speed-test

使用方式

import * from 'network-speed-test';
getSpeedWithImg("https://s2.ax1x.com/2019/08/13/mPJ2iq.jpg", 8.97).then(
    speed => {
        console.log(speed);
    }
)

getSpeedWithAjax('./speed.jpg').then(speed => {
    console.log(speed);
});

getNetSpeed('./speed.jpg', 3).then(speed => {
    console.log(speed);
});

getSpeedWithDnlink();

npm包地址

https://www.npmjs.com/package/network-speed-test

Github地址

https://github.com/penghuwan/network-speed-test

以上就是如何用JavaScipt测网速的详细内容,更多关于用JavaScipt测网速的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
屏蔽script注入小例子
Nov 12 Javascript
解析Javascript中中括号“[]”的多义性
Dec 03 Javascript
JS禁用页面上所有控件的实现方法(附demo源码下载)
Dec 17 Javascript
Javascript 正则表达式校验数字的简单实例
Nov 02 Javascript
JS实现拖拽的方法分析
Dec 20 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
Jan 16 Javascript
JS中Array数组学习总结
Jan 18 Javascript
JS中的phototype详解
Feb 04 Javascript
JS操作xml对象转换为Json对象示例
Mar 25 Javascript
基于Require.js使用方法(总结)
Oct 26 Javascript
基于vue.js中关于下拉框的值默认及绑定问题
Aug 22 Javascript
js+canvas实现转盘效果(两个版本)
Sep 13 Javascript
浅谈JS的二进制家族
如何使用vue3打造一个物料库
Ajax常用封装库——Axios的使用
May 08 #Javascript
微信小程序用户授权最佳实践指南
vue完美实现el-table列宽自适应
详解JS WebSocket断开原因和心跳机制
May 07 #Javascript
如何用threejs实现实时多边形折射
You might like
phpmyadmin的#1251问题
2006/11/25 PHP
用PHP实现 上一篇、下一篇的代码
2012/09/29 PHP
php中print(),print_r(),echo()的区别详解
2014/12/01 PHP
Jquery Ajax学习实例 向页面发出请求,返回XML格式数据
2010/03/14 Javascript
JavaScript Math.ceil() 函数使用介绍
2013/12/11 Javascript
JQuery中$.ajax()方法参数详解及应用
2013/12/12 Javascript
js实现网页随机切换背景图片的方法
2014/11/01 Javascript
jQuery Ajax调用WCF服务详细教程
2015/03/31 Javascript
使用AngularJS来实现HTML页面嵌套的方法
2015/06/17 Javascript
浅析四种常见的Javascript声明循环变量的书写方式
2015/10/14 Javascript
JavaScript的String字符串对象常用操作总结
2016/05/26 Javascript
js实现二级导航功能
2017/03/03 Javascript
javascript 开发之百度地图使用到的js函数整理
2017/05/19 Javascript
Vue动态组件实例解析
2017/08/20 Javascript
AngularJS动态添加数据并删除的实例
2018/02/27 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
2019/04/17 Javascript
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
Python中正则表达式的详细教程
2015/04/30 Python
详解python里使用正则表达式的分组命名方式
2017/10/24 Python
python遍历文件夹,指定遍历深度与忽略目录的方法
2018/07/11 Python
Python3 读、写Excel文件的操作方法
2018/10/20 Python
关于python中plt.hist参数的使用详解
2019/11/28 Python
python实现拼接图片
2020/03/23 Python
pycharm中导入模块错误时提示Try to run this command from the system terminal
2020/03/26 Python
在Python3.74+PyCharm2020.1 x64中安装使用Kivy的详细教程
2020/08/07 Python
Python实现小黑屋游戏的完整实例
2021/01/06 Python
html5 canvas-2.用canvas制作一个猜字母的小游戏
2013/01/07 HTML / CSS
阿拉伯世界最大的电子卖场:Souq埃及
2016/08/01 全球购物
Structs界面控制层技术
2013/10/11 面试题
卫校中专生个人自我评价
2013/09/19 职场文书
什么样的创业计划书可行性高?
2014/02/01 职场文书
小学语文国培感言
2014/03/04 职场文书
党员个人批评与自我批评
2014/10/14 职场文书
Html5通过数据流方式播放视频的实现
2021/04/27 HTML / CSS
有趣的二维码:使用MyQR和qrcode来制作二维码
2021/05/10 Python
windows下快速安装nginx并配置开机自启动的方法
2021/05/11 Servers