JavaScript'te internet hızı nasıl algılanır?


214

Kullanıcının internet hızını algılayıp sayfada gösterecek bir JavaScript sayfasını nasıl oluşturabilirim? Böyle bir şey “internet hızı ?? / ?? ise Kb / s ” .


1
@ Jakub, @Ankit: İnsanlar Flash'ı bunun için kullanabilir, ancak buna gerek yoktur . JavaScript ile yapamazsanız hiçbir neden yok.
TJ Crowder

İhtiyacınız olan şey bu: speedof.me/api.html
advncd

Yanıtlar:


288

Bir dereceye kadar mümkündür, ancak gerçekten doğru olmayacaktır, fikir, bilinen bir dosya boyutuna sahip görüntüyü yüklemek, o onloadzaman etkinliğinde o olayın tetiklenmesine ne kadar zaman geçtiğini ölçmek ve bu zamanı görüntü dosyası boyutuna bölmektir.

Örnek burada bulunabilir: Javascript kullanarak hızı hesaplayın

Burada önerilen düzeltmeyi uygulayan test durumu:

//JUST AN EXAMPLE, PLEASE USE YOUR OWN PICTURE!
var imageAddr = "http://www.kenrockwell.com/contax/images/g2/examples/31120037-5mb.jpg"; 
var downloadSize = 4995374; //bytes

function ShowProgressMessage(msg) {
    if (console) {
        if (typeof msg == "string") {
            console.log(msg);
        } else {
            for (var i = 0; i < msg.length; i++) {
                console.log(msg[i]);
            }
        }
    }
    
    var oProgress = document.getElementById("progress");
    if (oProgress) {
        var actualHTML = (typeof msg == "string") ? msg : msg.join("<br />");
        oProgress.innerHTML = actualHTML;
    }
}

function InitiateSpeedDetection() {
    ShowProgressMessage("Loading the image, please wait...");
    window.setTimeout(MeasureConnectionSpeed, 1);
};    

if (window.addEventListener) {
    window.addEventListener('load', InitiateSpeedDetection, false);
} else if (window.attachEvent) {
    window.attachEvent('onload', InitiateSpeedDetection);
}

function MeasureConnectionSpeed() {
    var startTime, endTime;
    var download = new Image();
    download.onload = function () {
        endTime = (new Date()).getTime();
        showResults();
    }
    
    download.onerror = function (err, msg) {
        ShowProgressMessage("Invalid image, or error downloading");
    }
    
    startTime = (new Date()).getTime();
    var cacheBuster = "?nnn=" + startTime;
    download.src = imageAddr + cacheBuster;
    
    function showResults() {
        var duration = (endTime - startTime) / 1000;
        var bitsLoaded = downloadSize * 8;
        var speedBps = (bitsLoaded / duration).toFixed(2);
        var speedKbps = (speedBps / 1024).toFixed(2);
        var speedMbps = (speedKbps / 1024).toFixed(2);
        ShowProgressMessage([
            "Your connection speed is:", 
            speedBps + " bps", 
            speedKbps + " kbps", 
            speedMbps + " Mbps"
        ]);
    }
}
<h1 id="progress">JavaScript is turned off, or your browser is realllllly slow</h1>

"Gerçek" hız testi hizmeti ile hızlı karşılaştırma büyük resim kullanırken 0.12 Mbps'lik küçük bir fark gösterdi.

Testin bütünlüğünü sağlamak için kodu Chrome geliştirme aracı azaltma etkinken çalıştırabilir ve ardından sonucun sınırlama ile eşleşip eşleşmediğini görebilirsiniz. (kredi user284130'a gider :))

Unutmamanız gereken önemli noktalar:

  1. Kullanılan görüntü uygun şekilde optimize edilmeli ve sıkıştırılmalıdır. Değilse, web sunucusu tarafından yapılan bağlantılarda varsayılan sıkıştırma hızı gerçekte olduğundan daha büyük gösterebilir. Başka bir seçenek sıkıştırılamaz dosya biçimi kullanmaktır, örn. Jpg. (Rauli Rajande'ye bunu işaret ettiği için teşekkürler ve Fluxine bana hatırlattığı için )

  2. Yukarıda açıklanan önbellek bozucu mekanizması, sorgu dizesi parametrelerini yok sayacak şekilde yapılandırılabilen bazı CDN sunucularıyla çalışmayabilir, bu nedenle görüntünün kendisinde önbellek denetim başlıklarını daha iyi ayarlar. (teşekkürler için orcaman bu out işaret ) )


8
Test görüntüsünün uygun şekilde optimize edilmesine ve sıkıştırılmasına dikkat edin. Değilse, web sunucusu tarafından yapılan bağlantılarda varsayılan sıkıştırma hızı gerçekte olduğundan daha büyük gösterebilir.
Rauli Rajande

3
Görüntünüzün test için uygun olduğundan emin olmak için küçük bir hile buldum: Chrome dev aracı aracı azaltma etkinken kodu çalıştırın ve sonucun sınırlama ile eşleşip eşleşmediğine bakın. Umarım bu birine yardımcı olabilir.
user284130

3
Rauli Rajande'ye katılmak: sıkıştırılamayan (veya neredeyse) bir dosyayı daha iyi kullanın veya web sunucusu sıkıştırma modülleri, ölçüyü geçersiz kılarak önemli ölçüde azaltabilir. Bir jpeg görüntüsü iyi bir seçim olacaktır.
Fluxine

1
Bu Javascript kodunu başarıyla kullanmış olanlar için, başlangıçta "download.onload" a giden aramalarla karşılaşmadınız mı? Ben de tam olarak bunu yaşıyorum ve hala nedenini bulmaya çalışıyorum.

2
@Dilip küçük resim daha az doğru test anlamına gelir, bilerek büyüktür. :)
Gölge Sihirbazı Sizin İçin

78

Eh, bu 2017, bu yüzden bir tür tahmin downlink hız bilgisi almak için şimdi (şu anda tarayıcılar arasında sınırlı bir destek olsa da) Ağ Bilgi API'sına sahipsiniz :

navigator.connection.downlink

Bu, saniye başına Mbits cinsinden etkin bant genişliği tahminidir. Tarayıcı, bu tahmini, son zamanlarda etkin olan bağlantılarda son zamanlarda gözlemlenen uygulama katmanı veriminden yapar. Söylemeye gerek yok, bu yaklaşımın en büyük avantajı sadece bant genişliği / hız hesaplaması için herhangi bir içerik indirmenize gerek olmamasıdır.

Buna ve diğer birkaç ilgili özelliğe buradan bakabilirsiniz

O (Kasım 2017 itibariyle) tarayıcılar arasında sınırlı destek ve farklı uygulamaları var etmek, şiddetle tavsiye ediyorum dolayı okumak bu ayrıntılı olarak


18
Kullanabilir miyim?
Francisco Presencia

2
Bunu kullanarak 10MBit'ten daha yüksek sayılar almıyorum. Bir sınır var mı?
Tobi

@Tobi Ben de 10MBit daha yüksek gibi görünmüyor, daha fazla 100MBit olmalıdır
camjocotem

Downlink tam olarak nedir? İndirme hızı falan mı?
gacat

@Tobi Ben de, eğer hız 10Mb üzerinde ise okumaya devam 10
Aramil

21

StackOverflow'daki bu diğer cevabın ana hatlarını çizerken , bunu çeşitli boyutlardaki dosyaların indirilmesini zamanlayarak (küçük başlangıç ​​yapın, bağlantı izin veriyorsa rampalayın), önbellek başlıklarıyla ve dosyanın gerçekten uzak sunucudan okunuyor ve önbellekten alınmıyor. Bu, mutlaka kendi sunucunuz olmasını gerektirmez (dosyalar S3'ten geliyor olabilir veya benzeri ), ancak bağlantı hızını test etmek için dosyaları almak için bir yere ihtiyacınız olacaktır.

Bununla birlikte, zaman içinde bant genişliği testleri, diğer pencerelerden indirilen diğer öğelerden, sunucunuzun hızından, yoldaki bağlantılardan vb. Etkilendiği için, güvenilir olmayan bir şekilde güvenilmezdir. Ancak kaba bir fikir edinebilirsiniz. bu tür bir teknik kullanarak.


1
@ Jakub: Yüklemek için bir yeriniz olmalı, ancak bunun için aynı tekniği kullanamamanız için hiçbir neden yok. Anında oluşturduğunuz verileri kullanabilir veya elbette, indirme testi için indirdiğiniz bazı verileri yeniden kullanabilirsiniz.
TJ Crowder

Peki yükleme işleminin ne zaman tamamlandığını nasıl anlarsınız?
Jakub Hampl

2
@ Jakub: Birkaç yoldan herhangi biri. iframeÖrneğin gizli bir form gönderirseniz , iframeveya bir çerezi doldurmak üzere yoklarsınız. Gönderiyi XMLHttpRequestyapmak için bir nesne kullanırsanız, tamamlanması için geri arama vardır.
TJ Crowder

18

Kullanıcı bağlantı hızının üzerinde çalıştığım bir sitedeki bazı özellikleri etkinleştirmek / devre dışı bırakmak için yeterince hızlı olup olmadığını belirlemek için hızlı bir yola ihtiyacım vardı. Örneğin, 3G veya Wi-Fi'yi açıkça ayırt edebilmek için testlerimde oldukça doğru çalışıyor, belki biri daha zarif bir versiyon veya hatta bir jQuery eklentisi yapabilir.

var arrTimes = [];
var i = 0; // start
var timesToTest = 5;
var tThreshold = 150; //ms
var testImage = "http://www.google.com/images/phd/px.gif"; // small image in your server
var dummyImage = new Image();
var isConnectedFast = false;

testLatency(function(avg){
  isConnectedFast = (avg <= tThreshold);
  /** output */
  document.body.appendChild(
    document.createTextNode("Time: " + (avg.toFixed(2)) + "ms - isConnectedFast? " + isConnectedFast)
  );
});

/** test and average time took to download image from server, called recursively timesToTest times */
function testLatency(cb) {
  var tStart = new Date().getTime();
  if (i<timesToTest-1) {
    dummyImage.src = testImage + '?t=' + tStart;
    dummyImage.onload = function() {
      var tEnd = new Date().getTime();
      var tTimeTook = tEnd-tStart;
      arrTimes[i] = tTimeTook;
      testLatency(cb);
      i++;
    };
  } else {
    /** calculate average of array items then callback */
    var sum = arrTimes.reduce(function(a, b) { return a + b; });
    var avg = sum / arrTimes.length;
    cb(avg);
  }
}


1
Benim durumumda en güvenilir cevap.
Abdalla Arbab

1
yükleme testi ne olacak?
Mart'ta

9

Görüntü hilesi harika ama testlerimde bazı ajax çağrılarından önce yüklenmek istedim.

2017'de uygun çözüm bir işçi kullanmaktır ( http://caniuse.com/#feat=webworkers ).

İşçi şöyle görünecek:

/**
 * 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
  );
};

İşçiyi çağıracak js dosyası:

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);
  }
};

Yazdığım Plone paketinden alınan kod:


5

Hızı test etmek için görüntüleri kullanmak daha iyidir. Ancak zip dosyalarıyla uğraşmak zorunda kalırsanız, aşağıdaki kod çalışır.

var fileURL = "your/url/here/testfile.zip";

var request = new XMLHttpRequest();
var avoidCache = "?avoidcache=" + (new Date()).getTime();;
request.open('GET', fileURL + avoidCache, true);
request.responseType = "application/zip";
var startTime = (new Date()).getTime();
var endTime = startTime;
request.onreadystatechange = function () {
    if (request.readyState == 2)
    {
        //ready state 2 is when the request is sent
        startTime = (new Date().getTime());
    }
    if (request.readyState == 4)
    {
        endTime = (new Date()).getTime();
        var downloadSize = request.responseText.length;
        var time = (endTime - startTime) / 1000;
        var sizeInBits = downloadSize * 8;
        var speed = ((sizeInBits / time) / (1024 * 1024)).toFixed(2);
        console.log(downloadSize, time, speed);
    }
}

request.send();

Bu, <10MB'lık dosyalarla çok iyi çalışmaz. Birden çok indirme denemesinde toplu sonuçlar çalıştırmanız gerekir.


3
Cevabın basitliğini seviyorum ve amacım için uyarladım: zaman damgaları için window.performance.now'a takas ettim , request.responseType = "blob" (MIME türleri geçerli değil), request.response.size için indirme boyutu ve hız hesaplama için 1000000 (Mbps SI birimlerinde olması gerektiğinden).
Rupert Rawnsley


1

Punit S cevabı sayesinde, dinamik bağlantı hızı değişikliğini tespit etmek için aşağıdaki kodu kullanabilirsiniz:

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

2
maalesef tüm tarayıcıları desteklemiyor. caniuse.com/#search=netinfo
axelioo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.