Determining Connection Speed with Javascript or PHP

I am trying to determine a users connection speed without making the page load any slower. Does anyone know how to do this with either JavaScript or PHP? I was thinking of preloading a small image with a timer before and after it but my code is returning no difference in time, even if the image is 1 MB. I think maybe it is not waiting for the preload before it runs the rest of the code but I don't know. Please help.
LVL 1
rbichonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

knightEknightCommented:
I don't know how accurate it's going to be using javascript anyway, but as far as the images go, make sure you are loading two different images -- otherwise the browser only loads it once even if you include it twice in the page.
ZvonkoSystems architectCommented:
Check this:

<script>
var startTime;
var fileSize= 4758;
function showSpeed(){
  var endTime = new Date();
  alert("Speed: "+((endTime-startTime)/1.024).toFixed(1)+" KB/s");
}

function testSpeed(){
  var newImg = new Image();
  newImg.onload = showSpeed;
  newImg.src = "http://www.experts-exchange.com/images/indexLogo.gif?time="+(startTime = new Date());
}

testSpeed();
</script>

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ZvonkoSystems architectCommented:
I use a T1 connection, but the speed was absolutely too high :-)
I did not divide by the fileSize.
Now is the attribute fileSize not provided by browsers that I tested, so you have two possibilities: hardcode the file size, like I did, or calculate aprox. bytes by multiplicate height * width (as in comment).

Here the test:

<script>
var startTime;
var fileSize = 4758;
function showSpeed(){
  var endTime = new Date();
  //var fileSize = this.width*this.height;
  alert("Speed: "+(fileSize/(endTime-startTime)*1.024).toFixed(1)+" KB/s");
}

function testSpeed(){
  var newImg = new Image();
  newImg.onload = showSpeed;
  newImg.src = "http://www.experts-exchange.com/images/indexLogo.gif?time="+(startTime = new Date());
}

testSpeed();
</script>

Your Guide to Achieving IT Business Success

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

rbichonAuthor Commented:
That is perfect! All I need is a rough estimate anyway. My end game is to figure out about how fast people are connecting and load different images accordingly so that the load time isn't too long for people on modems. Does it matter what size the preload image is? Is it more accurate if the image is larger?
hackman_3vilGuyCommented:
Use this XML. I think you need the DOCTYPE and other stuff:

<html xmlns:MSIE="urn:default" id="htmlText" style="width: 365px; height: 240px">
<HEAD>
<STYLE>
      MSIE\:CLIENTCAPS {behavior:url(#default#clientcaps)}
</STYLE>
</HEAD>
<body tabindex="-1">

<MSIE:CLIENTCAPS ID="idClCap" />

<script language="JavaScript">

var str = document.all.idClCap.connectionType;

alert ("Your connection is: " + str);
document.write("Your connection is: " + str + "<BR>");
        if (str == "lan")
                downloadSpeed = 800;     // good estimate for LAN - 800 KB/min
        else if (str == "offline")
            {
                downloadSpeed = 100;    // default to modem speed if offline
            isoffline = true;
                alert (document.all.idClCap.connectionType);
            }
        else
                downloadSpeed = 120;    // good estimate for 28.8kbps modem, 120 KB/min

alert ("Approximately " + downloadSpeed + "KB/Min");
document.write("Approximately " + downloadSpeed + "KB/Min");

</SCRIPT>
<p>This script shows your connection speed and connection with xml</p>
</BODY>
</HTML>
ZvonkoSystems architectCommented:
Here my next aproximation:

<script>
var avgSpeed = 8.2;
function showSpeed(){
  var endTime = new Date();
  var actSpeed = (this.fSize/(endTime-this.startTime)*1.024);
  avgSpeed = (avgSpeed + actSpeed)/2;
  alert("Speed: "+actSpeed.toFixed(1)+" KB/s  (averige: "+avgSpeed.toFixed(1)+" KB/s)");
}

function testSpeed(imgSrc,imgSize){
  var newImg = new Image();
  newImg.onload = showSpeed;
  newImg.fSize = imgSize;
  newImg.startTime = new Date();
  newImg.src = imgSrc+"?time="+(this.startTime = new Date());
}

testSpeed("http://www.experts-exchange.com/images/indexLogo.gif",4758);
testSpeed("http://www.experts-exchange.com/images/indexLogoPerson_01.gif",17194);
testSpeed("http://www.experts-exchange.com/images/indexLogoPerson_02.gif",17980);
testSpeed("http://www.experts-exchange.com/images/indexLogoPerson_03.gif",16124);
testSpeed("http://www.experts-exchange.com/images/indexLogoPerson_07.gif",18902);
</script>

I am so bad in Mathematics and hope that genious GwynforWeb will shine in and correct my mess :)

rbichonAuthor Commented:
That is a great way to do it but I need the users current connection speed. Because even on a high-speed connection, the transfer rate can dip pretty low on occation.

Zvonko, I have noticed that if the image has been loaded before, it doesn't try to do it again. This makes it look the second time like they are on a very fast connection, even if they are on a modem. Is there a way to force the client to download the image each time? I don't want to use cache control because it would affect the rest of the page.
ZvonkoSystems architectCommented:
In my example is no browser cache used.
The image are to be fetched every time fresh because of the ?time parameter in miliseconds.

rbichonAuthor Commented:
Thanks Zvonko. I used a mixture of your code and some code I found on CNET for their bandwidth meter (http://reviews.cnet.com/7004-7254_7-0.html). It is:

<script>
var startTime = new Date();
var fileSize = 2883 / 1024;
function showSpeed(){
  var endTime = new Date();
  elapse = (endTime-startTime) / 1000;
  kbps = (fileSize/elapse)*8*10*1.024;
  alert(kbps);
}

function testSpeed(){
  var newImg = new Image();
  newImg.onload = showSpeed;
  newImg.src = "images/load.jpg?time="+startTime.getMilliseconds();
}

testSpeed();
</script>

This seems to return a pretty accurate measure of the connection speed.
ZvonkoSystems architectCommented:
LOL :)
I got this after going once back after the image loading:
17435.9 Kbps - You     17435.9 kbps

 
 
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.