I would like to get a rough estimate of the users' upload speed without getting direct permission. This is only to distinguish really slow connections from very fast ones so accuracy is not super important...
Here's an implementation of this using XMLHttpRequest
expanding on @Yiğit Yener's idea.
Upload speed is dependent on two things: the user's connection speed and the server's connection speed. I made the assumption here that you want to test the speed between the user and your server. And with XMLHttpRequest
, that's really the only option because of the same-origin policy.
With upload speed, you don't need to return anything. You just need to POST
a large chunk of data to any page on your server. The easiest page to hit is the one you're already on. To do this you can leave the domain portion of the url out altogether in .open()
. POST
data is limited on some servers to two megabytes, so I used one to be safe. One is enough to get a decent reading.
To prevent the URL from being cached, I append a random number to the end.
url = '?cache=' + Math.floor( Math.random() * 10000 )
To prevent the POST
data from being gzipped, I use random data. The function allows you to pass the number of iterations you wish to check. Iterations are spaced out to every five seconds. The update
callback gets called each iteration with the speed of that check, and the moving average of all the checks. Use as many iterations as you wish to get your desired accuracy. If you just want a rough estimate, one iteration is enough.
It's called like this:
checkUploadSpeed( 10, function ( speed, average ) {
} );
You can try this code here.
You can try this on ThinkingStiff's own server, which is probably the fastest out of these all.
function checkUploadSpeed( iterations, update ) {
var average = 0,
index = 0,
timer = window.setInterval( check, 5000 ); //check every 5 seconds
check();
function check() {
var xhr = new XMLHttpRequest(),
url = '?cache=' + Math.floor( Math.random() * 10000 ), //random number prevents url caching
data = getRandomString( 1 ), //1 meg POST size handled by all servers
startTime,
speed = 0;
xhr.onreadystatechange = function ( event ) {
if( xhr.readyState == 4 ) {
speed = Math.round( 1024 / ( ( new Date() - startTime ) / 1000 ) );
average == 0
? average = speed
: average = Math.round( ( average + speed ) / 2 );
update( speed, average );
index++;
if( index == iterations ) {
window.clearInterval( timer );
};
};
};
xhr.open( 'POST', url, true );
startTime = new Date();
xhr.send( data );
};
function getRandomString( sizeInMb ) {
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_+`-=[]\{}|;':,./<>?", //random data prevents gzip effect
iterations = sizeInMb * 1024 * 1024, //get byte count
result = '';
for( var index = 0; index < iterations; index++ ) {
result += chars.charAt( Math.floor( Math.random() * chars.length ) );
};
return result;
};
};
checkUploadSpeed( 10, function ( speed, average ) {
document.getElementById( 'speed' ).textContent = 'speed: ' + speed + 'kbs';
document.getElementById( 'average' ).textContent = 'average: ' + average + 'kbs';
} );
<div id="speed">speed: 0kbs</div>
<div id="average">average: 0kbs</div>
JSFiddle servers where the demo is hosted are slower.
Click this button to go to the fiddle:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With