0

I attached my JavaScript snippet which can measure the internet speed. By sending a simple GET request to google.com each time, I able to receive a 200 OK response header. To overcome CORS, I run the script via console at the same tab where google.com was opened. I explain everything in the code section. But when I compare my output with services like fast.com and Ookla, It showing a huge difference. So kindly explain why this is happening? I'm I right or wrong? what about my JS script?

I attached the images of my output and the fast.com output.

//Internet speed calculation with JS ajax

function fire(){
//Get the request initiate time 
var start = new Date().getTime();

/* Each and every request should be unique. 
Stop getting resource from browser cache */
var val = Math.random();

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){

//If request successfully completed and ready to serve
if(this.readyState==4 && this.status==200){

//Get the time when request completed
var end = new Date().getTime();

//mesure time taken for a request Round-trip in seconds
var diff = (end - start)/1000;

//Get content length from request header in bytes and convert it to KB
let content = xhr.getResponseHeader("content-length")/1024;

//The print output statement
console.log("Request length : "+content.toFixed(2)+" Kb "+"completed in "+diff.toFixed(2) +" seconds...");
}    
}

//Send GET request while open google.com opened in browser to bypass CORS  
xhr.open("GET","https://www.google.com?cache="+val,true);
xhr.send();

}

//Winin 1 sec delay send request and clear after 10 sec
var timer = setInterval(fire, 1000);
setTimeout(function() { clearInterval(timer);}, 10000);type here

The output of my script

enter image description here

So 465.79 kb transferred in 3.48 sec

The output of fast.com

enter image description here

fast.com showing different statistics !

Note - Please do not suggest any 3rd party libraries, pre-built solution and services to complete the task. I already tried existing stackoverflow solution in my case.

//Solution from Stackoverflow
//Show speed of 5.01Mbps

let imageURL = "https://sample-videos.com/img/Sample-jpg-image-5mb.jpg"; 
let sizeinBytes = 5266467; 
let start, end;
let cache = "?rand=" + Math.random();

let image = new Image();
image.onload = function(){
    end = (new Date()).getTime();
    calculate();
};
start = (new Date()).getTime();
image.src = imageURL + cache;

function calculate(){
        timeDiffInSec = (end - start)/1000;
        let bits = sizeinBytes * 8;
        let Bps = (bits / timeDiffInSec).toFixed(2);
        let Kbps = (Bps / 1024).toFixed(2);
        let Mbps = (Kbps / 1024).toFixed(2);
        alert("Speed is : "+Mbps+" Mbps");   

}


//Slightly modified code of mine 
//Show speed of 1.01 Mbps 

let start = new Date().getTime();
let val = Math.random();

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(this.readyState==4 && this.status==200){
let end = new Date().getTime();
let diff = (end - start)/1000;
    let contentinBytes = xhr.getResponseHeader("content-length");
    let bits = contentinBytes * 8;

    let Bps = (bits / diff).toFixed(2);
    let Kbps = (Bps / 1024).toFixed(2);
    let Mbps = (Kbps / 1024).toFixed(2);
    alert("Speed is : "+Mbps+" Mbps"); 

}    
}

xhr.open("GET","https://www.google.com?cache="+val,true);
xhr.send();

But fast.com says 23Mbps, How it is possible ?

  • Please explain why [duplicate questions](https://stackoverflow.com/questions/5529718/how-to-detect-internet-speed-in-javascript) did not resolve the problem. – Yogi Nov 18 '22 at 08:40
  • @Yogi Because other solutions tested with an image loading concept (known size of image) and compare start and end time of request. But my approach is different. I am playing with HTTP headers. – Thanesh Prabaghan Nov 18 '22 at 08:51
  • Are you asking why downloading several tiny files is slower than a big file? At least that sounds obvious... – James Z Nov 18 '22 at 09:28
  • @James Z I think, it is not depend on file size. The speed KB/S OR Mb/s is not like famous solutions fast.com or ookla – Thanesh Prabaghan Nov 18 '22 at 09:39
  • Please mention if anything wrong in my code. – Thanesh Prabaghan Nov 18 '22 at 09:47
  • At least I would assume there's a lot more overhead & slowness for opening connection, starting transfer etc. when doing a lot of small files vs one big one. – James Z Nov 18 '22 at 14:44
  • Your code will not work correctly. It suffers from the same problem as the other SO solutions. To make an accurate measurement, the code must do multiple parallel downloads to utilize full bandwidth. I've verified that this works and matches the values from fast.com, etc. – Yogi Nov 19 '22 at 01:35
  • @James Z Your assumption is right. I should test with large file on single connection to measure internet speed. – Thanesh Prabaghan Nov 19 '22 at 01:40
  • @Yogi parallel downloads to utilize full bandwidth also tried. Please check the answer of this post. – Thanesh Prabaghan Nov 19 '22 at 06:19

1 Answers1

0

As mentioned in the comment, I tried to execute parallel ajax calls using promises, async and await. For example, 03 requests executed parallelly. The Parallel function will wait until all 03 requests to complete. Each request has 5MB in size.

<!DOCTYPE html>
<html>
  <head>
    <title>Measure Internet Speed</title>
   <script
  src="https://code.jquery.com/jquery-3.6.1.js"
  integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI="
  crossorigin="anonymous"></script>
  </head>
  
<body>

<h1><div id="process1"></div></h1><br>
<h1><div id="process2"></div></h1><br>
<h1><div id="process3"></div></h1><br>

<script type="text/javascript">

//Allow cross-orign in httaccess 
const url = "https://testsite9327.000webhostapp.com/chunk";

let p1 = new Promise((resolve,reject)=>{
return ajaxCall(resolve,reject);
});

let p2 = new Promise((resolve,reject)=>{
return ajaxCall(resolve,reject);
});

let p3 = new Promise((resolve,reject)=>{
return ajaxCall(resolve,reject);
});

function ajaxCall(resolve,reject){

let start = new Date().getTime();
let val = Math.random();

$.ajax({
  url:url+"?cache="+val,
  type:"GET",
  success: function(data, status, xhr){

    let end = new Date().getTime();
    let diff = (end - start)/1000;
    let contentinBytes = xhr.getResponseHeader("content-length");
    let bits = contentinBytes * 8;

    let Bps = (bits / diff).toFixed(2);
    let Kbps = (Bps / 1024).toFixed(2);
    let Mbps = (Kbps / 1024).toFixed(2);

    let res = Bps+","+Kbps+","+Mbps;        

    resolve(res);  
  },
  error:function(error){
    reject(error);
  }
});
  
}

async function Parallel(){
  await Promise.all([p1,p2,p3]).then((reply)=>{
     $('#process1').html(" Process 01 : "+reply[0].split(",")[0]+" Bps | "+reply[0].split(",")[1]+" Kbps | " +reply[0].split(",")[2]+" Mbps");
     $('#process2').html(" Process 02 : "+reply[1].split(",")[0]+" Bps | "+reply[1].split(",")[1]+" Kbps | " +reply[1].split(",")[2]+" Mbps");
     $('#process3').html(" Process 03 : "+reply[2].split(",")[0]+" Bps | "+reply[2].split(",")[1]+" Kbps | " +reply[2].split(",")[2]+" Mbps");      
     
     console.log("Parallel Processing done...!");

  }).catch((error)=>{
    console.log(error);
  });
}

Parallel();

</script>

</body>
</html>

The Output Image

But the output is not satisfying. Please mention any other ideas. It would be more welcome, if you provide any working JS code solution without 3rd party.