npm包地址

Github地址

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

前端判断网速的原理总结

(注:下面求的网速单位默认为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();

Github地址

 

参考文章

https://juejin.im/post/5b4de6b7e51d45190d55340b

 

知乎账号

 
 

当我们尝试用JavaScipt测网速的更多相关文章

  1. 【树莓派】Linux 测网速及树莓派源

    这篇文章比较杂,其中包含三点:linux环境中测试网络速度,树莓派下载软件的源,部分我写好的脚本: 一.Linux 测网速 Linux 测网速: sar -n DEV 1 100 1代表一秒统计并显示 ...

  2. iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码

    iOS精选源码 扩展内容的cell - folding-cell 一个近乎完整的可识别中国身份证信息的Demo 可自动快速... JPImageresizerView 仿微信的图片裁剪 带年月和至今以 ...

  3. CentOS测网速

    当发现上网速度变慢时,人们通常会先首先测试自己的电脑到网络服务提供商(通常被称为"最后一公里")的网络连接速度.在可用于测试宽带速度的网站中,Speedtest.net也许是使用最 ...

  4. linux中利用speedtest-cli测网速

    [root@elegant-snap-3 you-get]# wget https://raw.githubusercontent.com/sivel/speedtest-cli/master/spe ...

  5. 测网速 fping Linux查看网络即时网速 linux性能问题(CPU,内存,磁盘I/O,网络)

    Linux查看网络即时网速 fping 是ping 工具的加强版本 例出局域网中存活的主机 (Ubuntu apt-get装上  cnetos装不上) zzx@zzx11:~$ fping -a 19 ...

  6. Ubuntu16.04测网速

    wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0b4.tar.xz tar -xvJf Python-3.7.0b4.tar.xz c ...

  7. Linux测网速

    $ wget https://raw.github.com/sivel/speedtest-cli/master/speedtest_cli.py$ chmod a+rx speedtest_cli. ...

  8. 提升网速的路由器优化方法(UPnP、QoS、MTU、交换机模式、无线中继)

    在上一篇<为什么房间的 Wi-Fi 信号这么差>中,猫哥从微波炉.相对论.人存原理出发,介绍了影响 Wi-Fi 信号强弱的几大因素,接下来猫哥再给大家介绍几种不用升级带宽套餐也能提升网速的 ...

  9. Mac/ios 模拟器 测试模拟慢网速

    原文:http://www.heyuan110.com/2015/06/16/Mac%E6%B5%8B%E8%AF%95%E6%A8%A1%E6%8B%9F%E6%85%A2%E7%BD%91%E9% ...

随机推荐

  1. MYSQL手工注入(详细步骤)—— 待补充

    0x00 SQL注入的分类: (1)基于从服务器接收到的响应         ▲基于错误的 SQL 注入         ▲联合查询的类型         ▲堆查询注射         ▲SQL 盲注 ...

  2. [WPF自定义控件库]了解WPF的布局过程,并利用Measure为Expander添加动画

    1. 前言 这篇文章介绍WPF UI元素的两步布局过程,并且通过Resizer控件介绍只使用Measure可以实现些什么内容. 我不建议初学者做太多动画的工作,但合适的动画可以引导用户视线,提升用户体 ...

  3. 【题解】【A % B Problem(P1865)】-C++

    题目背景 题目名称是吸引你点进来的 实际上该题还是很水的 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m 接下来n行,每行两个整数 l,r 表示区间 输出格式: 对 ...

  4. requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))【已解决】

     问题: 跑python自动化时出现报错如下图 解决: requests请求时,后面加上参数:stream=True. 参考外国小哥:https://stackoverflow.com/questio ...

  5. 高性能javascript-总结(一)

    性能优化 第一章:加载和执行 总结: 将所有<script>标签放到页面底部.这能确保在脚本执行前页面已经渲染了. 合并脚本.<script>标签越少,加载越快,响应速度也更迅 ...

  6. Spring的注解问题

    Annotation(注解)概述 从JDK5.0开始, Java增加了对元数据(MetaData)的支持,也就是 Annotation(注解). Annotation其实就是代码里的特殊标记,它用于替 ...

  7. css 图片裁剪显示

    用object-fit:cover object-fit属性详解 object-fit:CSS 属性指定替换元素的内容应该如何适应到其使用的高度和宽度确定的框. object-fit:fill 被替换 ...

  8. [leetcode] 290. Word Pattern (easy)

    原题 思路: 建立两个哈希表,分别保存: 1 模式 :单词 2 单词 :是否出现过 水题 /** * @param {string} pattern * @param {string} str * @ ...

  9. PHP强制转换类型

    PHP强制转换类型   获取数据类型 : 1.如果想查看某个表达式的值和类型,用var_dump(). 2.如果只是想得到一个易读懂的类型的表达方式用于调试,用 gettype().3.要查看某个类型 ...

  10. 【Kali】kali linux的安装

    资源准备 制作U盘启动盘 准备kali_Linux的分区 禁用快速启动 安装kali_linux 在这篇Blog中笔者将会讲解如何安装kali_linux,kali可以安装到虚拟机上,但这里笔者强烈建 ...