Bagaimana saya bisa membuat halaman JavaScript yang akan mendeteksi kecepatan internet pengguna dan menampilkannya di halaman? Sesuatu seperti "kecepatan internet Anda adalah ?? / ?? Kb / s ” .
Bagaimana saya bisa membuat halaman JavaScript yang akan mendeteksi kecepatan internet pengguna dan menampilkannya di halaman? Sesuatu seperti "kecepatan internet Anda adalah ?? / ?? Kb / s ” .
Jawaban:
Mungkin sampai batas tertentu tetapi tidak akan benar-benar akurat, idenya adalah memuat gambar dengan ukuran file yang diketahui kemudian onload
mengukur peristiwa berapa banyak waktu berlalu sampai peristiwa itu dipicu, dan membagi waktu ini dalam ukuran file gambar.
Contoh dapat ditemukan di sini: Hitung kecepatan menggunakan javascript
Test case menerapkan perbaikan yang disarankan di sana:
//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>
Perbandingan cepat dengan layanan tes kecepatan "nyata" menunjukkan perbedaan kecil 0,12 Mbps saat menggunakan gambar besar.
Untuk memastikan integritas pengujian, Anda dapat menjalankan kode dengan pelambatan alat dev dev Chrome dan kemudian melihat apakah hasilnya cocok dengan batasan. (kredit masuk ke user284130 :))
Hal-hal penting yang perlu diingat:
Gambar yang digunakan harus dioptimalkan dan dikompresi dengan benar. Jika tidak, maka kompresi standar pada koneksi oleh server web mungkin menunjukkan kecepatan lebih besar dari yang sebenarnya. Pilihan lain adalah menggunakan format file yang tidak dapat dikompres, misalnya jpg. (Terima kasih Rauli Rajande karena menunjukkan ini dan Fluxine karena mengingatkan saya )
Mekanisme cache buster yang dijelaskan di atas mungkin tidak berfungsi dengan beberapa server CDN, yang dapat dikonfigurasikan untuk mengabaikan parameter string kueri, karenanya mengatur header kontrol cache yang lebih baik pada gambar itu sendiri. (Terima kasih orcaman untuk menunjukkan ini ) )
Nah, ini tahun 2017 sehingga Anda sekarang memiliki API Informasi Jaringan (walaupun dengan dukungan terbatas di semua browser seperti sekarang) untuk mendapatkan semacam perkiraan informasi kecepatan downlink:
navigator.connection.downlink
Ini adalah perkiraan bandwidth efektif dalam Mbits per detik. Browser membuat perkiraan ini dari throughput lapisan aplikasi yang baru-baru ini diamati melalui koneksi yang baru-baru ini aktif. Tidak perlu dikatakan, keuntungan terbesar dari pendekatan ini adalah Anda tidak perlu mengunduh konten apa pun hanya untuk perhitungan bandwidth / kecepatan.
Anda dapat melihat ini dan beberapa atribut terkait lainnya di sini
Karena dukungannya yang terbatas dan implementasi yang berbeda di seluruh browser (pada Nov 2017), sangat disarankan untuk membaca ini secara detail
Seperti yang saya uraikan dalam jawaban lain di sini di StackOverflow , Anda dapat melakukan ini dengan mengatur waktu pengunduhan file dari berbagai ukuran (mulai dari yang kecil, tingkatkan jika koneksi tampaknya memungkinkan), memastikan melalui header cache dan sedemikian rupa sehingga file tersebut benar-benar sedang dibaca dari server jarak jauh dan tidak diambil dari cache. Ini tidak selalu mengharuskan Anda memiliki server sendiri (file mungkin berasal dari S3 atau serupa), tetapi Anda akan memerlukan tempat untuk mendapatkan file untuk menguji kecepatan koneksi.
Yang mengatakan, tes bandwidth point-in-time terkenal tidak dapat diandalkan, karena mereka dipengaruhi oleh item lain yang diunduh di windows lain, kecepatan server Anda, tautan dalam perjalanan, dll., Dll. Tetapi Anda bisa mendapatkan ide kasar menggunakan teknik semacam ini.
iframe
, misalnya, Anda polling iframe
atau cookie untuk selesai. Jika Anda menggunakan XMLHttpRequest
objek untuk melakukan posting, ada panggilan balik untuk diselesaikan.
Saya memerlukan cara cepat untuk menentukan apakah kecepatan koneksi pengguna cukup cepat untuk mengaktifkan / menonaktifkan beberapa fitur di situs yang saya kerjakan, saya membuat skrip kecil ini yang rata-rata waktu yang diperlukan untuk mengunduh satu (kecil) gambar beberapa kali, ini berfungsi cukup akurat dalam pengujian saya, bisa membedakan dengan jelas antara 3G atau Wi-Fi misalnya, mungkin seseorang dapat membuat versi yang lebih elegan atau bahkan plugin jQuery.
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);
}
}
Trik gambarnya keren tetapi dalam pengujian saya memuat sebelum beberapa panggilan ajax saya ingin selesai.
Solusi yang tepat di 2017 adalah menggunakan pekerja ( http://caniuse.com/#feat=webworkers ).
Pekerja akan terlihat seperti:
/**
* 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
);
};
File js yang akan memanggil Pekerja:
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);
}
};
Kode diambil dari paket Plone yang saya tulis:
Lebih baik menggunakan gambar untuk menguji kecepatan. Tetapi jika Anda harus berurusan dengan file zip, kode di bawah ini berfungsi.
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();
Ini tidak akan bekerja dengan baik dengan file <10MB. Anda harus menjalankan hasil agregat pada beberapa upaya unduhan.
Saya membutuhkan sesuatu yang serupa, jadi saya menulis https://github.com/beradrian/jsbandwidth . Ini adalah penulisan ulang https://code.google.com/p/jsbandwidth/ .
Idenya adalah untuk membuat dua panggilan melalui Ajax, satu untuk mengunduh dan yang lainnya untuk mengunggah melalui POST.
Ini harus bekerja dengan keduanya jQuery.ajax
atau Angular $http
.
berkat jawaban Punit S, untuk mendeteksi perubahan kecepatan koneksi dinamis, Anda dapat menggunakan kode berikut:
navigator.connection.onchange = function () {
//do what you need to do ,on speed change event
console.log('Connection Speed Changed');
}