Checking someones bandwidth and loading content based on it
Asked Answered
D

6

11

I have seen a number of questions that don't answer this, is it possible to check someones bandwidth using java script and load specific content based on it?

The BBC seem to give me low quality images when using my mobile and in the middle of nowhere.

by the looks of this this cool service does this and its a CDN so it could be server side.

http://www.resrc.it/docs/

Does anyone know how they do it? or how I could do it using asp.net or javascript, or an community opensource plug in.

I think it may be possible with https://github.com/yahoo/boomerang/ but not sure this is its true purpose.

Dinodinoflagellate answered 21/12, 2012 at 10:6 Comment(5)
And when you are using your mobile and you are in the middle of civilization what happens? Do you know what a user-agent is used for?Viscoid
yeah it loads better quality images, this in on a blackberry.Dinodinoflagellate
By browser or by app? If you are using an app... it will access the hardware's info, signal strength and technology used to connect to the network (2G,3G, LTE, WiFi), so the app in this case can decide how much bandwidth will consume. By the way, browser is also an app, so, well... You better test it with your laptop, a USB modem, and a browser in the middle of nowhere and say if it still works.Viscoid
Just the standard blackberry browser, so yeah this could be doing this. Looks like its time to head out to the hills with the laptop!Dinodinoflagellate
See this: #5530218Flutter
J
9

Basically you do this like this:

  • Start a timer
  • Load an fixed size file e.g a image through an ajax call
  • Stop the timer
  • Take some samples and compute the average badwidth

Somethign like this could work:

//http://upload.wikimedia.org/wikipedia/commons/5/51/Google.png
//Size = 238 KB
function measureBW(cnt, cb) {
    var start = new Date().getTime();
    var bandwidth;
    var i = 0;
    (function rec() {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open('GET', 'http://upload.wikimedia.org/wikipedia/commons/5/51/Google.png', true);

        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState == 4) {
                var x = new Date().getTime() - start;
                bw = Number(((238 / (x / 1000))));
                bandwidth = ((bandwidth || bw) + bw) / 2;
                i++;
              if (i < cnt) {
                start = new Date().getTime();rec();
              }
                else cb(bandwidth.toFixed(0));
            }
        };
        xmlHttp.send(null);
    })();

}

measureBW(10, function (e) {
    console.log(e);
});

Not that var xmlHttp = new XMLHttpRequest(); won't work on all browsers, you should check for the UserAgent and use the right one

And of course its just an estimated value.

Heres a JSBin example

Jany answered 21/12, 2012 at 10:47 Comment(3)
This solution is more accurate than mine!Squier
@c5h8nnao4 .. Monosodium L-glutamate :))Ticklish
Disable caching before trying this out. Or as per example the first request would be downloaded from remote server and rest of the requests would be served from cache.Ulises
C
2
  1. Start a timer.
  2. Send a AJAX request to your server, requesting a file of known size.
  3. When the AJAX request's done loading, stop the timer, and calculate the bandwidth from the passed time and file size.

The problem with JavaScript is that users can disable it. (Which is more common on phones, that happen to be better off with smaller images)

Corporative answered 21/12, 2012 at 10:13 Comment(4)
This would work but could basing this on one Ajax request at one point in time be risky, your server may be under load or the clients network may be busy. I think it would be good to do this more than once and base the content on average bandwidth.Dinodinoflagellate
@Paul: That's a fair point. However, client-side, you don't want to wait to get images util after you have "stable" bandwidth data. I'd suggest loading the images with JavaScript, adding a 'load' event listener to these images, calculate bandwidth, and store the bandwidth locally. This way you can start loading a few small images, get a average bandwidth, and dynamically modify what images are loaded.Corporative
Do you think this will work? Do the same on server side using your own HTTP handler for special "knonw-size" files. Start the timer on server side, open the test file (e.g. your main site's logo) and send it by writing into the output stream. Once the EOF is reached (client finished loading content) then stop your timer.Viscoid
@AdrianSalazar: yea, same idea, but server-side.Corporative
S
2

I've knocked this up based on timing image downloads (ref: http://www.ehow.com/how_5804819_detect-connection-speed-javascript.html)

Word of warning though:

It says my speed is 1.81Mbps,

But according to SpeedTest.Net my speeds are this:

enter image description here

The logic of timing the download seems right but not sure if it's accurate?

Squier answered 21/12, 2012 at 10:51 Comment(1)
This is the difference because of server's regions speedtest.net always hits your local regions while aws.amazon.com may be in different regions.Zingale
V
1

Well, like I said in my comments, you can choose 2 approaches:

1) You are in the context of a mobile app, then you can query the technology used by the device directly so you can notify the server directly what type (and size) of content you area able to render. I think phone gap can help you with accessing some of the native mobile API's using JavaScript.

2) The server-timer thing. You can "serve" some files yourself, lets say you have a magic file in your landing page, that, as soon as the client request the file, you grab this HTTP request with a custom handler. You "manually" serve the file by writing to the output stream, and you measure the bytes send and the time it took to reach the EOF, then you can somehow measure the bandwith. Combine this with the session cookie and you have this information per connected browser.

Viscoid answered 21/12, 2012 at 11:11 Comment(0)
D
0

While this isn't an answer, it may be important to note that measuring bandwidth isn't always reliable.

http://www.smashingmagazine.com/2013/01/09/bandwidth-media-queries-we-dont-need-em/

To paraphrase the above:

...the number of bits downloaded divided by the time it took to download them...is true when you download a large file over a single warmed-up TCP connection. That is rarely the case. Typical page load scenario:

  1. Initial HTML page is downloaded using slow-start mechanism, so measurement will significantly underestimate the available bandwidth
  2. CSS and JavaScript external resources are loaded -- a collection of new TCP connections, all in their slow-start phase, and they are not all necessarily to the same destination server
  3. Images are loaded -- multiple connections, each one downloading a resource. The problem is that these connections are not always in the same phase of their life cycle. Some might be in the slow-start phase; some may have suffered a packet loss and, thus, reduced their window and the bandwidth they are trying to fill; and some might be warmed-up TCP connections, ready to fill the bandwidth. These TCP connections are not necessarily all to the same destination server, and the bandwidth towards the various destination servers might be different between one another.

So, estimating bandwidth is possible, but it is far from simple, and it is possible only for certain phases of the page-loading process. And because having several TCP connections to various destination servers is common (for example, a CDN could host the image resources of a Web page), we cannot really tell what is the bandwidth we want to measure.

Since this is an older question, the alternative suggestion at the end of the article is to consider the more recent srcset attribute for responsive imagery, which lets the browser decide which asset to load based on whatever it knows (which should be more than us). It sounds like it's weighted more towards just determining resolution, but maybe it'll get smarter as support goes up.

Dismantle answered 4/11, 2014 at 15:10 Comment(0)
P
0

I have released BwCh which is an open-source JavaScript API to detect bandwidth for web-based environments

It is built with ES2015. It uses some of the latest JavaScript innovation (window.navigator.connection currently supported in Chrome 48+ for Android as of April 2016) in order to provide a flexible method to detect bandwidth for both mobile and desktop devices. It fallbacks/complements to image pre-loading to detect bandwidth where those newest API are not available.

Paramorph answered 7/4, 2016 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.