How fast is your Internet?
Tags: javascript, programming, webdev, tutorial
Published: 2021-10-20 07:42:59

## How fast is your Internet? Lets find it out using **JavaScript**.
> Visual learner? Here's the [Video Tutorial](https://www.youtube.com/watch?v=_r955zGxgFQ).

In [this article](https://dev.to/0shuvo0/i-will-be-notified-if-you-click-this-7df) we have already learn that images can do more than just showing a graphic. Now in this tutorial we are once again going to use image to find out what is the download speed of our Internet.
{% link https://dev.to/0shuvo0/i-will-be-notified-if-you-click-this-7df %}
So in [this article](https://dev.to/0shuvo0/i-will-be-notified-if-you-click-this-7df) he have learned that if a website have an image then the browser will send an http request to the URL which is in the src of the image and then the server will send use back an Image file which will finally be shown to us. And obviously it takes some time for server to send us the file. Now what if we already knew the size of our image? Well then if we could just know how long it takes for the image to get sent we can do some calculation to figure out the download speed of our Internet.

So what you can do it first choose any image you want. Then find out the size of that image. ![How to check file size](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccn2ds05lylzsytakb0z.png)
Now lets upload it into our server. You can use any free hosting like [Github](github.com).
So far so good. Now we have a image with known size hosted in the server. Now we need to find out how long it takes for the server to send us the Image. To do that we are going to use the **Image** object in JavaScript. Basically we can get the current time when our code starts executing and again get the current time once the image is loaded. And if we subtract them will can know how long it took for the image to load. Okay lets create a utility function for that.
```js
function imageLoadTime(src){
    return new Promise((resolve, reject) => {
        let image = new Image()
        image.src = src
        let startTime = Date.now()
    
        image.onload = function(){
            let endTime = Date.now()
            resolve(endTime - startTime)
        }

        image.onerror = function(err){
            reject(err)
        }
    })
}

imageLoadTime("https://raw.githubusercontent.com/0shuvo0/internet-speed-test/main/test.gif").then(loadTime => {
   console.log(`Image took ${loadTime}ms to load,`)
})
```
![check how long image takes to load JavaScript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qse437v4ihn5lc7yqpxn.png)
 
But if we run the function again you might see this time the image almost took no time to load.
![Image cached](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oq5el5ekpt6lcb332ltg.png)
The reason for that is the browser is caching the image. And since we are trying to get Image from same url the browser is just sending us the cached image. To prevent this we can simply append some random and unique query string to the url. So lets do that.
```js
function imageLoadTime(src){
    return new Promise((resolve, reject) => {
        let image = new Image()
        
        //appending random number as query string in the url
        image.src = src + "?" + parseInt(Math.random() * 10000)
        let startTime = Date.now()
    
        image.onload = function(){
            let endTime = Date.now()
            resolve(endTime - startTime)
        }

        image.onerror = function(err){
            reject(err)
        }
    })
}
```
![Image cache resolved](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v751az75sk7antob3lhi.png)

 
Now we know the size of our image, how long it takes to load and the caching issue is also resolved. Very nice!!! ![Very nice meme template](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmafm817d1o3ksiufa0r.png)

So we can now do some calculation to determine the download speed of our Internet. Let's create a function that does the calculation and return download speed in kbps(Kilobits per second)
```js
const imgURL = "https://raw.githubusercontent.com/0shuvo0/internet-speed-test/main/test.gif"
let imgSize = 1343591 //image size in bytes
imgSize *= 8 //converting image size in bytes to bits by multiplying by 8

function imageLoadTime(src){
    return new Promise((resolve, reject) => {
        let image = new Image()
        
        //appending random number as query string in the url
        image.src = src + "?" + parseInt(Math.random() * 10000)
        let startTime = Date.now()
    
        image.onload = function(){
            let endTime = Date.now()
            resolve(endTime - startTime)
        }

        image.onerror = function(err){
            reject(err)
        }
    })
}

async function getDownloadSpeed(src, size){
    let loadTime = await imageLoadTime(src)
    //Just in case the image was cached, we don't want load time to be 0
    //It would raise division by zero error
    if(loadTime < 1) loadTime = 1
    let speed_bps = size / loadTime
    let speed_kbps = speed_bps / 1024

    return speed_kbps
}

getDownloadSpeed(imgURL, imgSize).then(speed => {
    console.log(`Your download speed in ${speed}kb/s`)
}).catch(err => console.log(err))
```
![Internet speed demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/piob4qgezzafcm3uclle.png)
 
 
And boom now we can get our internet speed using JavaScript 😎. Okay the result contains too many decimal places places so lets fix that by saying `return +speed_kbps.toFixed(2)`, So there will be only two digits after decimal.

But to make our result even more accurate we can run the  `getDownloadSpeed` function a bunch of time and get the average of that. Let's do that.
### Finished codes:
```js
const imgURL = "https://raw.githubusercontent.com/0shuvo0/internet-speed-test/main/test.gif"
let imgSize = 1343591 //image size in bytes
imgSize *= 8 //converting image size in bytes to bits by multiplying by 8
//How many time the test should run
const TEST_COUNT = 30

function imageLoadTime(src){
    return new Promise((resolve, reject) => {
        let image = new Image()
        
        //appending random number as query string in the url
        image.src = src + "?" + parseInt(Math.random() * 10000)
        let startTime = Date.now()
    
        image.onload = function(){
            let endTime = Date.now()
            resolve(endTime - startTime)
        }

        image.onerror = function(err){
            reject(err)
        }
    })
}

async function getDownloadSpeed(src, size){
    let loadTime = await imageLoadTime(src)
    //Just in case the image was cached, we don't want load time to be 0
    //It would raise division by zero error
    if(loadTime < 1) loadTime = 1
    let speed_bps = size / loadTime
    let speed_kbps = speed_bps / 1024

    return +speed_kbps.toFixed(2)
}

async function run(){
   let test_results = []

   for(let i = 0; i < TEST_COUNT; i++){
        let speed = await getDownloadSpeed(imgURL, imgSize)   
        test_results.push(speed)
        console.log(`${i + 1} out of ${TEST_COUNT} test ran!`)
    }

    //getting the average download speed
    let sum = test_results.reduce((a, b) => a + b, 0)
    let result = sum / test_results.length

    console.log("All test finished!!!")
    console.log(`Your download speed is ${result.toFixed(2)}kb/s`)
}
 
run()
```
![Final codes demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awws37x2bf9z36097vto.png)
 
 
> Still the result won't be sure accurate because **where the server of our image is located** and **how much traffic is currently on the server** etc matters. But it should be good enough for us.

## Yayyyyyy every thing works.
![time to celebrate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8kjpb480tq9upgkam2c4.png)

That's all for this one. Make sure you check out my other articles.
{% user 0shuvo0 %}