js实现网络测速、每秒下载速度、估算下载时间公式

来源:程序思维浏览:3628次
js实现网络测速、每秒下载速度、估算下载时间公式

一、延迟与网速

通过js加载一张1x1的极小图片,测试出图片加载的所用的时长。如果换一个几百KB的图片,则可心用来计算下载网速

document.write('<input type="button" value="停止计时" onclick="clearTimeout(timeid) " />   ');
document.write('<input type="button" value="继续计时" onclick="ld()" />   ');
document.write('<div id="msg">正在测试网络延迟,请稍后...</div>');
var n = 0,tcp,timeid;
var ld = function() {
    var tcp,t = ( + new Date),img = new Image;
    img.onload = function(){
        var tcp =( + new Date) - t;
        n=n+1;
        console.log(n + ':  ' + tcp + '    ' + ( + new Date));
        document.getElementById("msg").innerText=tcp;
        if(n<100) timeid=setTimeout("ld()", 2000);
    }
    img.src = "png_1x1.png?" + Math.random(); //一张200多B的图片
};
ld();

但是,第一次加载图像时,它将比后续加载花费更长的时间,即使我们确保图像没有被缓存。因为第一次在两个主机(在我们的例子中是浏览器和服务器)之间打开TCP连接时,它们需要“握手”。一旦建立连接,它就会保持打开状态,直到两端都通过类似的握手决定关闭它。我们现在可以稍微修改我们的代码以考虑TCP握手的时间,并相应地测量延迟。

document.write('<input type="button" value="停止计时" onclick="clearTimeout(timeid) " />   ');
document.write('<input type="button" value="继续计时" onclick="ld()" />   ');
document.write('<div id="msg">正在测试网络延迟,请稍后...</div>');
var n = 0,tcp,timeid;
var ld = function() {
    var tcp,t = ( + new Date),img = new Image;
    img.onload = function(){
        var tcp =( + new Date) - t;
        n=n+1;
        console.log(n + ':  ' + tcp + '    ' + ( + new Date));
        document.getElementById("msg").innerText=tcp;
        if(n<100) timeid=setTimeout("ld()", 2000);
    }
    img.src = "png_1x1.png?" + Math.random();
};
var img_start = new Image;
img_start.onload = function(){ld();}
img_start.src = "png_1x1.png?" + Math.random();

同类版本实例

<!doctype html>
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>js实现的网速测试方法</title>
</head>
<body>
<script>
        document.write("<div id='div1'>正在下载测速图片,请稍后...</div>");var szsrc = "https://upload.wikimedia.org/wikipedia/commons/5/51/Google.png?id="+Math.round();
        var st = new Date();
        document.write(" <IMG height=300 alt=测试图片 src='"+szsrc+"'  width=400 onload=showspeed() >");
        function showspeed()
        {
          var fs = 1.46*1024;  //图片文件大小(KB)
          var l = 2;    //小数点的位数
          var et = new Date();
          alltime = fs*1000/(et - st)  //下载时间
          Lnum = Math.pow(10,l)
          calcspeed = Math.round(alltime*Lnum)/Lnum
          document.getElementById("div1").innerHTML = "您的下载速度为:"+calcspeed+" (KB/秒)  带宽约" + Math.round(calcspeed/128*Lnum)/Lnum  + "M";
        }
</script>
</body>
</html>

它的实现原理是,通过下载一张远程的图片,然后用js计算,计算公式是:文件大小/下载时间。

注意,下载图片大小要合适,且要把大小写入代码中,还有大小是1024进制的。还有延迟和网速都与服务器有关,图片地址可心用比较大的公司没有防盗链图片

二、AJAX版

ajax版的有两个好处,一是图片文件大小js可以自己读取,二是当然是异步啦。。。

<!doctype html>
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>js实现的网速测试方法</title>
</head>
<body>
<script>
function measureBW(fn) {
    var startTime, endTime, fileSize;
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
        if(xhr.readyState === 2){
            startTime = Date.now();
        }
        if (xhr.readyState === 4 && xhr.status === 200) {
            endTime = Date.now();
            fileSize = xhr.responseText.length;
            console.log(fileSize);
            var speed = fileSize  / ((endTime - startTime)/1000) / 1024;
            fn && fn(Math.floor(speed))
        }
    }
    xhr.open("GET", "https://upload.wikimedia.org/wikipedia/commons/5/51/Google.png?id=" + Math.random(), true);
    xhr.send();
}

measureBW((speed)=>{
    document.write("<div id='div1'>"+speed + " KB/s</div>");
    console.log(speed + " KB/s");  //215 KB/sec
})
</script>
</body>
</html>

同样,考虑到http请求需要建立连接,以及等待响应,这些过程也会消耗一些时间,所以以上的方法可能不会准确的检测出网络带宽。

我们可以同时发出多次请求,来减少http请求建立连接,等待响应的影响,参考如下代码:

function measureBW(fn,time) {
    time = time || 1;
    var startTime, endTime, fileSize;
    var count = time ;
    var _this = this;
    function measureBWSimple () {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4 && xhr.status === 200) {
                if(!fileSize){
                    fileSize = xhr.responseText.length;
                }
                count --;
                if(count<=0){
                    endTime = Date.now();
                    var speed = fileSize * time  / ((endTime - startTime)/1000) / 1024;
                    fn && fn(Math.floor(speed));
                }
            }
        }
        xhr.open("GET", "https://upload.wikimedia.org/wikipedia/commons/5/51/Google.png?" + Math.random(), true);
        xhr.send();
    }
    startTime = Date.now();
    for(var x = time;x>0;x--){
        measureBWSimple()
    }
}

measureBW((speed)=>{
    console.log(speed + " KB/sec");  //913 KB/sec
},10)

同理可用1像素图还测延迟

三、API类

在 Chrome65+ 的版本中,添加了一些原生的方法可以检测有关设备正在使用的连接与网络进行通信的信息。

参考如下代码,我们就可以检测到网络带宽:

function measureBW () {
    return navigator.connection.downlink;
}
measureBW() ;
navigator.connection.downlink 会返回以(兆比特/秒)为单位的有效带宽估计值(参考MDN),这和我们常用的(KB/sec)有所差别,所以我们需要再做一下单位换算,参考如下代码:

function measureBW () {
    return navigator.connection.downlink * 1024 /8;   //单位为KB/sec
}
measureBW() ;
我们还可以通过 navigator.connection 上的 change 事件来监听网络带宽的变化:

navigator.connection.addEventListener('change', measureBW());


再上一个,不错的收藏


document.write('<div id="msg">正在测试网络延迟,请稍后...</div>');
document.write('<a href="#">电信网路</a>    <span class="classtime" xl-name="电信网路"></span><br>');
document.write('<a href="#">联通网路</a>    <span class="classtime" xl-name="联通网路"></span>');
var jump=1,t={},autourl=new Array(),autoname=[];
autourl[1]="http://image.baidu.com/"; //这个是电信服务器站点
autourl[2]="https://www.baidu.com/"; //这个是联通服务器站点
autoname[1]="电信网路";
autoname[2]="联通网路";
(function(){
    for(var i=1;i<autourl.length;i++){
        var img = new Image;
        //img.onerror= auto(autourl[i]);
        img.onerror= (function(j){
            return function(){
                t[autourl[j]] =(new Date())- t[autourl[j]];  //记入时间差
                console.log(autourl[j] + "    :" + t[autourl[j]] + "ms"); //console.log(t[url] + "ms");
                document.querySelector('[xl-name="'+autoname[j]+'"]').innerHTML =  t[autourl[j]] + ' ms';
                console.log(jump);
                if(jump) {
                    jump=0;
                    document.getElementById("msg").innerText = '3秒后进入【' + autoname[j] + '】';
                    //setTimeout(function(){top.location=url;},3000); //setTimeout("top.location='" + url + "';",3000);   //3s 即3000ms
                    setTimeout(function(){window.location.replace(autourl[j]);},3000);
                }
            }
        })(i);
        //闭包传值
        img.src = autourl[i] + Math.random();
        t[autourl[i]] = (+new Date());//记录开始载入时间
    }
})();

估算下载时间公式:

定时器:1s

文件大小:Size

已下载的部分:Downloaded

前一秒已下载的部分:Downloaded_old

剩余时间:(Size – DownLoad) / (Downloaded – Downloaded_old)
精品好课
React实战视频教程仿京东移动端电商
React是前端最火的框架之一,就业薪资很高,本课程教您如何快速学会React并应用到实战,对正在工作当中或打算学习React高薪就业的你来说,那么这门课程便是你手中的葵花宝典。
VUE2+VUE3视频教程从入门到精通(全网最全的Vue课程)
VUE是目前最火的前端框架之一,就业薪资很高,本课程教您如何快速学会VUE+ES6并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习VUE高薪就...
jQuery视频教程从入门到精通
jquery视频教程从入门到精通,课程主要包含:jquery选择器、jquery事件、jquery文档操作、动画、Ajax、jquery插件的制作、jquery下拉无限加载插件的制作等等......
HTML5基础入门视频教程易学必会
HTML5基础入门视频教程,教学思路清晰,简单易学必会。适合人群:创业者,只要会打字,对互联网编程感兴趣都可以学。课程概述:该课程主要讲解HTML(学习HTML5的必备基础语言)、CSS3、Javascript(学习...
最新完整React视频教程从入门到精通纯干货纯实战
React是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习React高薪就...
最新完整React+VUE视频教程从入门到精,企业级实战项目
React和VUE是目前最火的前端框架,就业薪资很高,本课程教您如何快速学会React和VUE并应用到实战,教你如何解决内存泄漏,常用库的使用,自己封装组件,正式上线白屏问题,性能优化等。对正在工作当中或打算学习Re...
Vue2+Vue3+ES6+TS+Uni-app开发微信小程序从入门到实战视频教程
2021年最新Vue2+Vue3+ES6+TypeScript和uni-app开发微信小程序从入门到实战视频教程,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己...
HTML5视频播放器video开发教程
适用人群1、有html基础2、有css基础3、有javascript基础课程概述手把手教你如何开发属于自己的HTML5视频播放器,利用mp4转成m3u8格式的视频,并在移动端和PC端进行播放支持m3u8直播格式,兼容...
收藏
扫一扫关注我们