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

 再上一个,不错的收藏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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 @   笠航  阅读(14434)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示