Làm cách nào tôi có thể tạo một trang JavaScript sẽ phát hiện tốc độ internet của người dùng và hiển thị nó trên trang? Một cái gì đó giống như tốc độ internet của bạn là ?? / ?? Kb / sv .
Làm cách nào tôi có thể tạo một trang JavaScript sẽ phát hiện tốc độ internet của người dùng và hiển thị nó trên trang? Một cái gì đó giống như tốc độ internet của bạn là ?? / ?? Kb / sv .
Câu trả lời:
Ở một mức độ nào đó có thể nhưng sẽ không thực sự chính xác, ý tưởng là tải hình ảnh với kích thước tệp đã biết sau đó trong onload
sự kiện của nó đo thời gian trôi qua cho đến khi sự kiện đó được kích hoạt và chia thời gian này cho kích thước tệp hình ảnh.
Ví dụ có thể được tìm thấy ở đây: Tính tốc độ bằng cách sử dụng javascript
Trường hợp thử nghiệm áp dụng các sửa chữa được đề xuất ở đó:
//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>
So sánh nhanh với dịch vụ kiểm tra tốc độ "thực" cho thấy sự khác biệt nhỏ 0,12 Mbps khi sử dụng hình ảnh lớn.
Để đảm bảo tính toàn vẹn của kiểm tra, bạn có thể chạy mã với công cụ điều chỉnh Chrome dev được bật và sau đó xem kết quả có khớp với giới hạn không. (tín dụng chuyển đến user284130 :))
Những điều quan trọng cần ghi nhớ:
Hình ảnh đang được sử dụng phải được tối ưu hóa và nén đúng cách. Nếu không, thì nén mặc định trên các kết nối của máy chủ web có thể hiển thị tốc độ lớn hơn thực tế. Một tùy chọn khác là sử dụng định dạng tệp không nén được, ví dụ jpg. (cảm ơn Rauli Rajande đã chỉ ra điều này và Fluxine đã nhắc nhở tôi )
Cơ chế buster cache được mô tả ở trên có thể không hoạt động với một số máy chủ CDN, có thể được cấu hình để bỏ qua các tham số chuỗi truy vấn, do đó tốt hơn là thiết lập các tiêu đề kiểm soát bộ đệm trên chính hình ảnh. (cảm ơn orcaman đã chỉ ra điều này ) )
Chà, đây là năm 2017 nên hiện tại bạn đã có API Thông tin mạng (mặc dù có hỗ trợ hạn chế trên các trình duyệt) để có được một số loại thông tin tốc độ đường xuống ước tính :
navigator.connection.downlink
Đây là ước tính băng thông hiệu quả tính bằng Mbits mỗi giây. Trình duyệt đưa ra ước tính này từ thông lượng của lớp ứng dụng được quan sát gần đây trên các kết nối hoạt động gần đây. Không cần phải nói, ưu điểm lớn nhất của phương pháp này là bạn không cần tải xuống bất kỳ nội dung nào chỉ để tính toán băng thông / tốc độ.
Bạn có thể xem xét điều này và một vài thuộc tính liên quan khác ở đây
Do đó là hỗ trợ giới hạn và triển khai khác nhau trên các trình duyệt (tính đến tháng 11 năm 2017), rất muốn giới thiệu đọc này một cách chi tiết
Như tôi phác thảo trong câu trả lời khác ở đây trên StackOverflow , bạn có thể thực hiện việc này bằng cách định thời gian tải xuống các tệp có kích thước khác nhau (bắt đầu nhỏ, tăng tốc nếu kết nối dường như cho phép), đảm bảo thông qua các tiêu đề bộ đệm và sao cho tệp thực sự được đọc từ máy chủ từ xa và không được truy xuất từ bộ đệm. Điều này không nhất thiết yêu cầu bạn phải có máy chủ của riêng mình (các tệp có thể đến từ S3 hoặc tương tự), nhưng bạn sẽ cần một nơi nào đó để lấy các tệp từ đó để kiểm tra tốc độ kết nối.
Điều đó nói rằng, kiểm tra băng thông tại thời điểm nổi tiếng là không đáng tin cậy, vì chúng bị ảnh hưởng bởi các mục khác được tải xuống trong các cửa sổ khác, tốc độ của máy chủ của bạn, liên kết trên đường, v.v., nhưng bạn có thể hiểu sơ bộ sử dụng loại kỹ thuật này.
iframe
Ví dụ: nếu bạn gửi biểu mẫu cho một ẩn , bạn sẽ thăm dò ý kiến iframe
hoặc cookie để hoàn thành. Nếu bạn sử dụng một XMLHttpRequest
đối tượng để thực hiện bài đăng, sẽ có một cuộc gọi lại để hoàn thành.
Tôi cần một cách nhanh chóng để xác định xem tốc độ kết nối của người dùng có đủ nhanh để bật / tắt một số tính năng trong trang web tôi đang làm hay không, tôi đã tạo tập lệnh nhỏ này tính trung bình thời gian cần để tải xuống một hình ảnh (nhỏ) nhiều lần, nó hoạt động khá chính xác trong các thử nghiệm của tôi, ví dụ như có thể phân biệt rõ ràng giữa 3G hoặc Wi-Fi, có thể ai đó có thể tạo phiên bản thanh lịch hơn hoặc thậm chí là một 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);
}
}
Thủ thuật hình ảnh rất tuyệt nhưng trong các thử nghiệm của tôi, nó đã được tải trước khi một số cuộc gọi ajax tôi muốn hoàn thành.
Giải pháp thích hợp trong năm 2017 là sử dụng một công nhân ( http://caniuse.com/#feat=webworkers ).
Công nhân sẽ trông như:
/**
* 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
);
};
Tệp js sẽ gọi Worker:
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);
}
};
Mã được lấy từ gói Plone tôi đã viết:
Tốt hơn là sử dụng hình ảnh để kiểm tra tốc độ. Nhưng nếu bạn phải xử lý các tệp zip, đoạn mã dưới đây hoạt động.
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();
Điều này sẽ không hoạt động tốt với các tệp <10MB. Bạn sẽ phải chạy kết quả tổng hợp trên nhiều lần tải xuống.
Tôi cần một cái gì đó tương tự, vì vậy tôi đã viết https://github.com/beradrian/jsbandband . Đây là bản viết lại của https://code.google.com.vn/p/jsbandband/ .
Ý tưởng là thực hiện hai cuộc gọi thông qua Ajax, một cuộc gọi để tải xuống và cuộc gọi khác để tải lên qua POST.
Nó nên hoạt động với cả hai jQuery.ajax
hoặc Angular $http
.
nhờ câu trả lời của Punit S, để phát hiện thay đổi tốc độ kết nối động, bạn có thể sử dụng mã sau:
navigator.connection.onchange = function () {
//do what you need to do ,on speed change event
console.log('Connection Speed Changed');
}