如何用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 相关文章推荐
javascript实现轮显新闻标题链接
Aug 13 Javascript
javascript模拟实现C# String.format函数功能代码
Nov 25 Javascript
采用call方式实现js继承
May 20 Javascript
一个Action如何调用两个不同的方法
May 22 Javascript
基于javascript数组实现图片轮播
May 02 Javascript
AngularJS入门教程之更多模板详解
Aug 19 Javascript
bootstrap表格分页实例讲解
Dec 30 Javascript
bootstrap jquery dataTable 异步ajax刷新表格数据的实现方法
Feb 10 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
Sep 20 Javascript
JavaScript中的相等操作符使用详解
Dec 21 Javascript
详解微信小程序之提高应用速度小技巧
Jan 07 Javascript
vue form表单post请求结合Servlet实现文件上传功能
Jan 22 Vue.js
浅谈JS的二进制家族
如何使用vue3打造一个物料库
Ajax常用封装库——Axios的使用
May 08 #Javascript
微信小程序用户授权最佳实践指南
vue完美实现el-table列宽自适应
详解JS WebSocket断开原因和心跳机制
May 07 #Javascript
如何用threejs实现实时多边形折射
You might like
PHP信号量基本用法实例详解
2016/02/12 PHP
php实现贪吃蛇小游戏
2016/07/26 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
2018/08/10 PHP
Javascript实现获取窗口的大小和位置代码分享
2014/12/04 Javascript
简介AngularJS的视图功能应用
2015/06/17 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
2016/03/01 Javascript
两行代码轻松搞定JavaScript日期验证
2016/08/03 Javascript
Jquery获取当前城市的天气信息
2016/08/05 Javascript
AnjularJS中$scope和$rootScope的区别小结
2016/09/18 Javascript
BootStrap3使用错误记录及解决办法
2016/12/22 Javascript
jQuery读取XML文件的方法示例
2017/02/03 Javascript
AngularJS入门教程二:在路由中传递参数的方法分析
2017/05/27 Javascript
NodeJS实现视频转码的示例代码
2017/11/18 NodeJs
vue+element实现批量删除功能的示例
2018/02/28 Javascript
微信小程序+腾讯地图开发实现路径规划绘制
2019/05/22 Javascript
微信小程序 冒泡事件原理解析
2019/09/27 Javascript
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
基于javascript实现移动端轮播图效果
2020/12/21 Javascript
Python中实现从目录中过滤出指定文件类型的文件
2015/02/02 Python
致Python初学者 Anaconda入门使用指南完整版
2018/04/05 Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
2018/07/07 Python
Python中__slots__属性介绍与基本使用方法
2018/09/05 Python
Python判断一个三位数是否为水仙花数的示例
2018/11/13 Python
css3隔行变换色实现示例
2014/02/19 HTML / CSS
阿里巴巴英国:Alibaba英国
2019/12/11 全球购物
英国钻石公司:British Diamond Company
2020/02/16 全球购物
俄罗斯便宜的在线服装商店:GroupPrice
2020/04/10 全球购物
澳大利亚美容产品及化妆品在线:Activeskin
2020/06/03 全球购物
老总助理工作岗位职责
2014/02/06 职场文书
经济管理毕业生求职信
2014/03/15 职场文书
信息合作协议书
2014/10/09 职场文书
大学教师个人总结
2015/02/10 职场文书
爱的教育读书笔记
2015/06/26 职场文书
四群教育工作总结
2015/08/10 职场文书
优秀新员工事迹材料
2019/05/13 职场文书
《正面管教》读后有感:和善而坚定的旅程
2019/12/19 职场文书