Compare commits

2 Commits
master ... demo

Author SHA1 Message Date
Franklin
26117efcf0 Delete CNAME 2023-02-23 17:03:51 +01:00
Franklin
30b903d7da Create CNAME 2023-02-23 17:00:45 +01:00
2 changed files with 94 additions and 75 deletions

View File

@@ -10,20 +10,26 @@ and runs great on static hosting.
You simply upload the `index.html` file and generate You simply upload the `index.html` file and generate
the binary testing files. the binary testing files.
> [!TIP] - [Example](#example)
> The number precision can be changed up to 3 decimals using the arrow keys on your keyboard.
> [!TIP]
> The speedtest is at its best when the connection is as
> short as possible. For example, on your NAS or RPi to
> check on your LAN bandwidth.
- [Installation](#installation) - [Installation](#installation)
- [Note on testing](#note-on-testing) - [Note on testing](#note-on-testing)
- [Unlicense](#unlicense) - [Unlicense](#unlicense)
- [Author](#author) - [Author](#author)
## Example
The link below has the same HTML file (with stats)
and is basic static webhosting with no backend
processing. The test files were generated using the
`fallocate` command.
<https://speedtest.fvdm.com/>
You can change the number precision up to 3 decimals using the arrow
keys on your keyboard.
## Installation ## Installation
Just clone the repo: Just clone the repo:
@@ -80,6 +86,15 @@ These commands only create the files in the filesystem.
No bytes are actually written to the storage. No bytes are actually written to the storage.
The suffix `m` is megabytes and `g` is gigabytes and so on. The suffix `m` is megabytes and `g` is gigabytes and so on.
Or you can download them from my server.
**Please don't hotlink!!**
* [1mb.bin](https://fvdm.com/speedtest/1mb.bin)
* [5mb.bin](https://fvdm.com/speedtest/5mb.bin)
* [10mb.bin](https://fvdm.com/speedtest/10mb.bin)
* [100mb.bin](https://fvdm.com/speedtest/100mb.bin)
## Note on testing ## Note on testing
@@ -98,6 +113,10 @@ my provider's speedtest I get double at least. Doing the same to my
LiquidSky box in Frankfurt I easily get over 900 Mbit. So there is a LiquidSky box in Frankfurt I easily get over 900 Mbit. So there is a
bottleneck somewhere between the web server and my home ISP. bottleneck somewhere between the web server and my home ISP.
The speedtest is at its best when the connection is as
short as possible. For example, on your NAS or RPi to
check on your LAN bandwidth.
Unlicense Unlicense
--------- ---------

View File

@@ -139,8 +139,8 @@
let binaryData; let binaryData;
// control precision // control precision
function onKeyDown( ev ) { function onKeyDown (ev) {
switch ( ev.code ) { switch (ev.code) {
case 'ArrowUp': case 'ArrowUp':
case 'ArrowRight': case 'ArrowRight':
decimals++; decimals++;
@@ -155,15 +155,15 @@
} }
} }
document.addEventListener( 'keydown', onKeyDown ); document.addEventListener ('keydown', onKeyDown);
// store <button> tags in array // store <button> tags in array
const btns = Array.from( document.querySelectorAll( 'button' ) ); const btns = Array.from (document.querySelectorAll ('button'));
// add click handler to buttons // add click handler to buttons
btns.forEach( btn => { btns.forEach (btn => {
btn.addEventListener( 'click', testDownload ); btn.addEventListener ('click', testDownload);
} ); });
/** /**
@@ -174,22 +174,22 @@
* @return {string} Rounded number with trailing zeros * @return {string} Rounded number with trailing zeros
*/ */
function dec ( num, deci ) { function dec (num, deci) {
const int = parseInt( num, 10 ); const int = parseInt (num, 10);
const flo = parseFloat( ( num % 1 ).toFixed( deci ) ); const flo = parseFloat ((num % 1).toFixed(deci));
const len = ( String( flo ).split( '.' )[1] || '' ).length; const len = (String (flo).split ('.')[1] || '').length;
const diff = deci - len; const diff = deci - len;
let res = String( int + flo ); let res = String (int + flo);
if ( ! flo && diff ) { if (!flo && diff) {
res += '.'; res += '.';
for ( let i = 0; i < diff; i++ ) { for (let i = 0; i < diff; i++) {
res += '0'; res += '0';
} }
} }
if ( flo && diff > 0 ) { if (flo && diff > 0) {
for ( let i = 0; i < diff; i++ ) { for (let i = 0; i < diff; i++) {
res += '0'; res += '0';
} }
} }
@@ -204,25 +204,25 @@
* @return {void} * @return {void}
*/ */
function testDone( updown, evBtn, evReq ) { function testDone (updown, evBtn, evReq) {
const diff = ( Date.now() - start ) / 1000; const diff = (Date.now() - start) / 1000;
if ( updown === 'download' ) { if (updown === 'download') {
binaryData = req.response; binaryData = req.response;
testUpload( evBtn ); testUpload (evBtn);
} }
else { else {
binaryData = null; binaryData = null;
resultString = resultString =
dec( avg.download, 1 ) dec (avg.download, 1)
+ ' / ' + dec( avg.upload, 1 ) + ' / ' + dec (avg.upload, 1)
+ ' Mb' + ' Mb'
; ;
document.querySelector( 'progress' ).style.visibility = 'hidden'; document.querySelector ('progress').style.visibility = 'hidden';
document.querySelector( '#result' ).className = 'resultDone'; document.querySelector ('#result').className = 'resultDone';
document.querySelector( '#result' ).innerHTML = resultString; document.querySelector ('#result').innerHTML = resultString;
document.querySelector( '#eta' ).innerHTML = dec( diff, 2 ) + ' sec'; document.querySelector ('#eta').innerHTML = dec (diff, 2) + ' sec';
req = null; req = null;
} }
@@ -236,8 +236,8 @@
* @return {void} * @return {void}
*/ */
function testRunning ( updown, ev ) { function testRunning (updown, ev) {
const now = Date.now(); const now = Date.now ();
let percent = 0.0; let percent = 0.0;
let Bps = 0; let Bps = 0;
@@ -246,26 +246,26 @@
let total = ev.total; let total = ev.total;
let diff = 0; let diff = 0;
if ( updown === 'upload' ) { if (updown === 'upload') {
total = binaryData.size; total = binaryData.size;
} }
if ( ev.lengthComputable && total ) { if (ev.lengthComputable && total) {
diff = ( now - start ) / 1000; diff = (now - start) / 1000;
Bps = ev.loaded / diff; Bps = ev.loaded / diff;
mbit = Bps / 1024 / 1024 * 8; mbit = Bps / 1024 / 1024 * 8;
avg[updown] = mbit; avg[updown] = mbit;
percent = ev.loaded / total * 100.0; percent = ev.loaded / total * 100.0;
eta = ( total - ev.loaded ) / Bps; eta = (total - ev.loaded) / Bps;
} }
if ( updown === 'upload' ) { if (updown === 'upload') {
percent = 100 - percent; percent = 100 - percent;
} }
document.querySelector( 'progress' ).value = percent; document.querySelector ('progress').value = percent;
document.querySelector( '#result' ).innerHTML = dec( avg[updown], decimals ) + ' Mbit/s'; document.querySelector ('#result').innerHTML = dec (avg[updown], decimals) + ' Mbit/s';
document.querySelector( '#eta' ).innerHTML = dec( eta, decimals ) + ' sec'; document.querySelector ('#eta').innerHTML = dec (eta, decimals) + ' sec';
} }
@@ -277,69 +277,69 @@
* @return {void} * @return {void}
*/ */
function testDownload ( btnEv ) { function testDownload (btnEv) {
if ( req ) { if (req) {
req.abort(); req.abort ();
} }
req = new XMLHttpRequest; req = new XMLHttpRequest;
start = Date.now(); start = Date.now ();
btns.forEach( btn => { btns.forEach (btn => {
btn.className = ''; btn.className = '';
} ); });
btnEv.target.className = 'choice'; btnEv.target.className = 'choice';
document.querySelector( 'progress' ).value = 0; document.querySelector ('progress').value = 0;
document.querySelector( 'progress' ).style.visibility = 'visible'; document.querySelector ('progress').style.visibility = 'visible';
req.onprogress = progEv => { req.onprogress = (progEv) => {
testRunning( 'download', progEv ); testRunning ('download', progEv);
}; };
req.onreadystatechange = reqEv => { req.onreadystatechange = (reqEv) => {
if ( req.readyState === 4 ) { if (req.readyState === 4) {
testDone( 'download', btnEv, reqEv ); testDone ('download', btnEv, reqEv);
} }
}; };
// load file avoiding the cache // load file avoiding the cache
req.open( 'GET', btnEv.target.dataset.file, true ); req.open ('GET', btnEv.target.dataset.file, true);
req.responseType = 'blob'; req.responseType = 'blob';
req.send( null ); req.send (null);
} }
function testUpload ( btnEv ) { function testUpload (btnEv) {
if ( req ) { if (req) {
req.abort(); req.abort ();
} }
req = new XMLHttpRequest; req = new XMLHttpRequest;
start = Date.now(); start = Date.now ();
if ( req.upload ) { if (req.upload) {
req.upload.onprogress = progEv => { req.upload.onprogress = (progEv) => {
testRunning( 'upload', progEv ); testRunning ('upload', progEv);
}; };
req.upload.onloadend = reqEv => { req.upload.onloadend = (reqEv) => {
testDone( 'upload', btnEv, reqEv ); testDone ('upload', btnEv, reqEv);
}; };
} }
else { else {
req.onprogress = progEv => { req.onprogress = (progEv) => {
testRunning( 'upload', progEv ); testRunning ('upload', progEv);
}; };
req.onreadystatechange = onreadystatechange = reqEv => { req.onreadystatechange = onreadystatechange = (reqEv) => {
if ( req.readyState === 4 ) { if (req.readyState === 4) {
testDone( 'upload', btnEv, reqEv ); testDone ('upload', btnEv, reqEv);
} }
}; };
} }
req.open( 'POST', '?nocache=' + start, true ); req.open ('POST', '?nocache=' + start, true);
req.send( binaryData ); req.send (binaryData);
} }
</script> </script>
</body> </body>