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>

注意,下载图片大小要合适,且要把大小写入代码中,还有大小是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());

 

相关链接:

https://baijiahao.baidu.com/s?id=1620927782246861487&wfr=spider&for=pc

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

 再上一个,不错的收藏

    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());//记录开始载入时间
        }
    })();

 

posted @ 2018-12-31 22:17  笠航  阅读(...)  评论(...编辑  收藏