Checking someones bandwidth and loading content based on it

江枫思渺然 提交于 2019-12-03 14:04:50

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

  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)

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:

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

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.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!