我如何创建一个JavaScript页面,将检测用户的互联网速度,并显示在页面上?比如“你的网速是??/??”Kb / s”。


当前回答

我需要类似的东西,所以我写了https://github.com/beradrian/jsbandwidth。这是https://code.google.com/p/jsbandwidth/的重写。

其思想是通过Ajax进行两个调用,一个用于下载,另一个用于通过POST上传。

它应该与jQuery一起工作。ajax或Angular $http。

其他回答

由于Punit S的回答,为了检测动态连接速度的变化,你可以使用以下代码:

navigator.connection.onchange = function () {
 //do what you need to do ,on speed change event
 console.log('Connection Speed Changed');
}

图像技巧很酷,但在我的测试中,它是在我想完成的一些ajax调用之前加载的。

2017年合适的解决方案是使用工人(http://caniuse.com/#feat=webworkers)。

工人看起来像这样:

/**
 * This function performs a synchronous request
 * and returns an object contain informations about the download
 * time and size
 */
function measure(filename) {
  var xhr = new XMLHttpRequest();
  var measure = {};
  xhr.open("GET", filename + '?' + (new Date()).getTime(), false);
  measure.start = (new Date()).getTime();
  xhr.send(null);
  measure.end = (new Date()).getTime();
  measure.len = parseInt(xhr.getResponseHeader('Content-Length') || 0);
  measure.delta = measure.end - measure.start;
  return measure;
}

/**
 * Requires that we pass a base url to the worker
 * The worker will measure the download time needed to get
 * a ~0KB and a 100KB.
 * It will return a string that serializes this informations as
 * pipe separated values
 */
onmessage = function(e) {
  measure0 = measure(e.data.base_url + '/test/0.bz2');
  measure100 = measure(e.data.base_url + '/test/100K.bz2');
  postMessage(
    measure0.delta + '|' +
    measure0.len + '|' +
    measure100.delta + '|' +
    measure100.len
  );
};

调用Worker的js文件:

var base_url = PORTAL_URL + '/++plone++experimental.bwtools';
if (typeof(Worker) === 'undefined') {
  return; // unsupported
}
w = new Worker(base_url + "/scripts/worker.js");
w.postMessage({
  base_url: base_url
});
w.onmessage = function(event) {
  if (event.data) {
    set_cookie(event.data);
  }
};

摘自我编写的Plone包的代码:

https://github.com/collective/experimental.bwtools/blob/master/src/experimental/bwtools/browser/static/scripts/

好吧,现在是2017年,所以你现在有网络信息API(尽管目前跨浏览器的支持有限)来获得某种估计的下行速度信息:

navigator.connection.downlink

这是以Mbits / sec为单位的有效带宽估计。浏览器根据最近观察到的应用程序层在最近活动连接上的吞吐量进行估计。不用说,这种方法的最大优点是,您不需要下载任何内容,只是为了带宽/速度计算。

你可以看看这个和其他一些相关的属性

由于它的支持有限,并且跨浏览器的实现不同(截至2017年11月),强烈建议详细阅读这篇文章

尽管这是旧的和回答,我想分享的解决方案,我做出了它2020年的基础上的影子巫师说不再战争的解决方案

我只是将它合并到一个对象中,该对象具有随时运行的灵活性,并在指定的mbps高于或低于测量结果时运行回调。

可以在包含testConnectionSpeed对象后的任何位置启动测试

/**
* @param float    mbps               - Specify a limit of mbps.
* @param function more(float result) - Called if more mbps than specified limit.
* @param function less(float result) - Called if less mbps than specified limit.
*/
testConnectionSpeed.run(mbps, more, less)

例如:

var testConnectionSpeed = { imageAddr : "https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg", // this is just an example, you rather want an image hosted on your server downloadSize : 2707459, // Must match the file above (from your server ideally) run:function(mbps_max,cb_gt,cb_lt){ testConnectionSpeed.mbps_max = parseFloat(mbps_max) ? parseFloat(mbps_max) : 0; testConnectionSpeed.cb_gt = cb_gt; testConnectionSpeed.cb_lt = cb_lt; testConnectionSpeed.InitiateSpeedDetection(); }, InitiateSpeedDetection: function() { window.setTimeout(testConnectionSpeed.MeasureConnectionSpeed, 1); }, result:function(){ var duration = (endTime - startTime) / 1000; var bitsLoaded = testConnectionSpeed.downloadSize * 8; var speedBps = (bitsLoaded / duration).toFixed(2); var speedKbps = (speedBps / 1024).toFixed(2); var speedMbps = (speedKbps / 1024).toFixed(2); if(speedMbps >= (testConnectionSpeed.max_mbps ? testConnectionSpeed.max_mbps : 1) ){ testConnectionSpeed.cb_gt ? testConnectionSpeed.cb_gt(speedMbps) : false; }else { testConnectionSpeed.cb_lt ? testConnectionSpeed.cb_lt(speedMbps) : false; } }, MeasureConnectionSpeed:function() { var download = new Image(); download.onload = function () { endTime = (new Date()).getTime(); testConnectionSpeed.result(); } startTime = (new Date()).getTime(); var cacheBuster = "?nnn=" + startTime; download.src = testConnectionSpeed.imageAddr + cacheBuster; } } // start test immediatly, you could also call this on any event or whenever you want testConnectionSpeed.run(1.5, function(mbps){console.log(">= 1.5Mbps ("+mbps+"Mbps)")}, function(mbps){console.log("< 1.5Mbps("+mbps+"Mbps)")} )

我成功地使用它来加载低分辨率的媒体慢网络连接。你必须玩一点,因为一方面,图像越大,测试就越合理,另一方面,对于慢速连接,测试将花费更长的时间,在我的情况下,我特别不希望慢速连接的用户加载大量mb。

改进了John Smith的答案,一个漂亮而干净的解决方案,返回一个Promise,因此可以与async/await一起使用。返回以Mbps为单位的值。

const imageAddr = 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg';
const downloadSize = 2707459; // this must match with the image above

let startTime, endTime;
async function measureConnectionSpeed() {
  startTime = (new Date()).getTime();
  const cacheBuster = '?nnn=' + startTime;

  const download = new Image();
  download.src = imageAddr + cacheBuster;
  // this returns when the image is finished downloading
  await download.decode();
  endTime = (new Date()).getTime();
  const duration = (endTime - startTime) / 1000;
  const bitsLoaded = downloadSize * 8;
  const speedBps = (bitsLoaded / duration).toFixed(2);
  const speedKbps = (speedBps / 1024).toFixed(2);
  const speedMbps = (speedKbps / 1024).toFixed(2);
  return Math.round(Number(speedMbps));
}