一、延遲與網速
通過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());//記錄開始載入時間 } })();