1. 程式人生 > >JS 測試網路速度與網路延遲

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 = "http://7qin.applinzi.com/themes/dmeng/images/w.gif?" + Math.random(); }; 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 = "http://1.7qin.applinzi.com/themes/dmeng/images/w.gif?" + Math.random();
};
var img_start = new Image;
img_start.onload = function(){ld();}
img_start.src = "http://1.7qin.applinzi.com/themes/dmeng/images/w.gif?" + 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