javascript 检查某人的带宽并根据它加载内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13988051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:23:50  来源:igfitidea点击:

Checking someones bandwidth and loading content based on it

javascriptbandwidthcontent-delivery-network

提问by Paul

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?

我看到很多问题都没有回答这个问题,是否可以使用 java 脚本检查某人的带宽并基于它加载特定内容?

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

BBC 似乎在使用我的手机和在偏僻的地方给我提供低质量的图像。

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

看起来这个很酷的服务是这样做的,它是一个 CDN,所以它可以是服务器端。

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

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.

有谁知道他们是如何做到的?或者我如何使用 asp.net 或 javascript 或社区开源插件来做到这一点。

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

我认为https://github.com/yahoo/boomerang/可能是可能的,但不确定这是它的真正目的。

采纳答案by Moritz Roessler

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
  • 启动计时器
  • 通过ajax调用加载固定大小的文件,例如图像
  • 停止计时器
  • 取一些样本并计算平均 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

并非这不适用于var xmlHttp = new XMLHttpRequest();所有浏览器,您应该检查 UserAgent 并使用正确的

And of course its just an estimated value.

当然,这只是一个估计值。

Heres a JSBinexample

这是一个JSBin示例

回答by Greg

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

我敲了这件事基于时序图像下载(参考:http://www.ehow.com/how_5804819_detect-connection-speed-javascript.html

Word of warning though:

警告的话

It says my speed is 1.81Mbps,

它说我的速度是1.81Mbps

But according to SpeedTest.Net my speeds are this:

但根据 SpeedTest.Net 我的速度是这样的:

enter image description here

在此处输入图片说明

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

下载计时的逻辑似乎是正确的,但不确定它是否准确?

回答by Cerbrus

  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.
  1. 启动计时器。
  2. 向您的服务器发送 AJAX 请求,请求一个已知大小的文件。
  3. 当 AJAX 请求完成加载时,停止计时器,并根据传递的时间和文件大小计算带宽。

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)

JavaScript 的问题在于用户可以禁用它。(这在手机上更常见,使用较小的图像会更好)

回答by Adrian Salazar

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.

1)您处于移动应用程序的上下文中,然后您可以直接查询设备使用的技术,以便您可以直接通知服务器您区域能够呈现的内容类型(和大小)。我认为 phone gap 可以帮助您使用 JavaScript 访问一些本机移动 API。

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.

2)服务器定时器的事情。您可以自己“提供”一些文件,假设您的登录页面中有一个魔法文件,一旦客户端请求该文件,您就可以使用自定义处理程序获取此 HTTP 请求。您通过写入输出流来“手动”提供文件,并测量发送的字节数和到达 EOF 所需的时间,然后您可以以某种方式测量带宽。将此与会话 cookie 结合起来,您就可以在每个连接的浏览器中获得此信息。

回答by drzaus

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/

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.

...下载的位数除以下载它们所花费的时间...当您通过单个预热的 TCP 连接下载大文件时,这是正确的。很少有这种情况。典型的页面加载场景:

  1. 初始 HTML 页面使用慢启动机制下载,因此测量将显着低估可用带宽
  2. 加载 CSS 和 JavaScript 外部资源——一组新的 TCP 连接,都处于慢启动阶段,它们不一定都指向同一个目标服务器
  3. 图像被加载——多个连接,每个连接下载一个资源。问题是这些连接并不总是处于其生命周期的同一阶段。有些可能处于缓慢启动阶段;有些人可能遭受了数据包丢失,从而减少了他们的窗口和他们试图填充的带宽;有些可能是预热的 TCP 连接,准备填充带宽。这些 TCP 连接不一定都连接到同一目标服务器,并且通往不同目标服务器的带宽可能彼此不同。

因此,估计带宽是可能的,但它远非简单,并且仅在页面加载过程的某些阶段是可能的。并且因为有多个 TCP 连接到不同的目标服务器很常见(例如,CDN 可以托管网页的图像资源),我们无法真正确定我们想要测量的带宽是多少。

Since this is an older question, the alternative suggestion at the end of the article is to consider the more recent srcsetattributefor 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.

由于这是一个较旧的问题,文章末尾的替代建议是考虑响应式图像的更新srcset属性,它让浏览器根据它所知道的(应该比我们更多)决定加载哪个资产。听起来它更倾向于确定分辨率,但随着支持的增加,它可能会变得更聪明。

回答by Arnaud Leyder

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

我发布了BwCh,它是一个开源 JavaScript API,用于检测基于 Web 的环境的带宽

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.

它是用 ES2015 构建的。它使用了一些最新的 JavaScript 创新(截至 2016 年 4 月 Android 版 Chrome 48+ 目前支持 window.navigator.connection),以提供一种灵活的方法来检测移动和桌面设备的带宽。它回退/补充图像预加载以检测那些最新 API 不可用的带宽。