Added customizable grace time at beginning of tests; GET parameters can now be used in the URLs in the settings; Minor changes
This commit is contained in:
parent
cce7c7a93f
commit
2254001aff
5 changed files with 95 additions and 42 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ugly.bat
|
47
doc.md
47
doc.md
|
@ -1,7 +1,7 @@
|
||||||
# HTML5 Speedtest
|
# HTML5 Speedtest
|
||||||
|
|
||||||
> by Federico Dossena
|
> by Federico Dossena
|
||||||
> Version 4.2.4, June 15 2017
|
> Version 4.2.5, June 16 2017
|
||||||
> [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/)
|
> [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/)
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,32 +95,32 @@ format:
|
||||||
* `5` = Test aborted
|
* `5` = Test aborted
|
||||||
* __dlStatus__ is either
|
* __dlStatus__ is either
|
||||||
* Empty string (not started or aborted)
|
* Empty string (not started or aborted)
|
||||||
* Download speed in Megabit/s as a number with 2 digits
|
* Download speed in Megabit/s as a number with 2 decimals
|
||||||
* The string "Fail" (test failed)
|
* The string "Fail" (test failed)
|
||||||
* __ulStatus__ is either
|
* __ulStatus__ is either
|
||||||
* Empty string (not started or aborted)
|
* Empty string (not started or aborted)
|
||||||
* Upload speed in Megabit/s as a number with 2 digits
|
* Upload speed in Megabit/s as a number with 2 decimals
|
||||||
* The string "Fail" (test failed)
|
* The string "Fail" (test failed)
|
||||||
* __pingStatus__ is either
|
* __pingStatus__ is either
|
||||||
* Empty string (not started or aborted)
|
* Empty string (not started or aborted)
|
||||||
* Estimated ping in milliseconds as a number with 2 digits
|
* Estimated ping in milliseconds as a number with 2 decimals
|
||||||
* The string "Fail" (test failed)
|
* The string "Fail" (test failed)
|
||||||
* __clientIp__ is either
|
* __clientIp__ is either
|
||||||
* Empty string (not fetched yet or failed)
|
* Empty string (not fetched yet or failed)
|
||||||
* The client's IP address as a string
|
* The client's IP address as a string
|
||||||
* __jitterStatus__ is either
|
* __jitterStatus__ is either
|
||||||
* Empty string (not started or aborted)
|
* Empty string (not started or aborted)
|
||||||
* Estimated jitter in milliseconds as a number with 2 digits (lower = stable connection)
|
* Estimated jitter in milliseconds as a number with 2 decimals (lower = stable connection)
|
||||||
* The string "Fail" (test failed)
|
* The string "Fail" (test failed)
|
||||||
|
|
||||||
### Starting the test
|
### Starting the test
|
||||||
To start the test, send the start command to the worker:
|
To start the test with the default settings, which is usually the best choice, send the start command to the worker:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
w.postMessage('start')
|
w.postMessage('start')
|
||||||
```
|
```
|
||||||
|
|
||||||
This starts the test with the default settings, which is usually the best choice. If you want, you can change these settings and pass them to the worker as JSON with like this:
|
If you want, you can change these settings and pass them to the worker as JSON when you start it, like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
w.postMessage('start {"param1": "value1", "param2": "value2", ...}')
|
w.postMessage('start {"param1": "value1", "param2": "value2", ...}')
|
||||||
|
@ -139,7 +139,7 @@ w.postMessage('start {"param1": "value1", "param2": "value2", ...}')
|
||||||
* __url_dl__: path to garbage.php or a large file to use for the download test
|
* __url_dl__: path to garbage.php or a large file to use for the download test
|
||||||
* Default: `garbage.php`
|
* Default: `garbage.php`
|
||||||
* __Important:__ path is relative to js file
|
* __Important:__ path is relative to js file
|
||||||
* __url_ul__: path to ab empty file or empty.php to use for the upload test
|
* __url_ul__: path to an empty file or empty.php to use for the upload test
|
||||||
* Default: `empty.php`
|
* Default: `empty.php`
|
||||||
* __Important:__ path is relative to js file
|
* __Important:__ path is relative to js file
|
||||||
* __url_ping__: path to an empty file or empty.php to use for the ping test
|
* __url_ping__: path to an empty file or empty.php to use for the ping test
|
||||||
|
@ -148,7 +148,9 @@ w.postMessage('start {"param1": "value1", "param2": "value2", ...}')
|
||||||
* __url_getIp__: path to getIP.php or replacement
|
* __url_getIp__: path to getIP.php or replacement
|
||||||
* Default: `getIP.php`
|
* Default: `getIP.php`
|
||||||
* __Important:__ path is relative to js file
|
* __Important:__ path is relative to js file
|
||||||
* __enable_quirks__: enables browser-specific optimizations. These optimizations override some of the default settings below. They do not override settings that are explicitly set.
|
|
||||||
|
#### Advanced test parameters
|
||||||
|
* __enable_quirks__: enables browser-specific optimizations. These optimizations override some of the default settings. They do not override settings that are explicitly set.
|
||||||
* Default: `true`
|
* Default: `true`
|
||||||
* __garbagePhp_chunkSize__: size of chunks sent by garbage.php in megabytes
|
* __garbagePhp_chunkSize__: size of chunks sent by garbage.php in megabytes
|
||||||
* Default: `20`
|
* Default: `20`
|
||||||
|
@ -170,6 +172,12 @@ w.postMessage('start {"param1": "value1", "param2": "value2", ...}')
|
||||||
* `2`: Ignore all errors
|
* `2`: Ignore all errors
|
||||||
* Default: `1`
|
* Default: `1`
|
||||||
* Recommended: `1`
|
* Recommended: `1`
|
||||||
|
* __time_dlGraceTime__: How long to wait (in seconds) before actually measuring the download speed. This is a good idea because we want to wait for the TCP window to be at its maximum (or close to it)
|
||||||
|
* Default: `1.5`
|
||||||
|
* Recommended: `>=0`
|
||||||
|
* __time_ulGraceTime__: How long to wait (in seconds) before actually measuring the upload speed. This is a good idea because we want to wait for the buffers to be full (avoids the peak at the beginning of the test)
|
||||||
|
* Default: `3`
|
||||||
|
* Recommended: `>=1`
|
||||||
* __allow_fetchAPI__: allow the use of Fetch API for the download test instead of regular XHR. Experimental, not recommended.
|
* __allow_fetchAPI__: allow the use of Fetch API for the download test instead of regular XHR. Experimental, not recommended.
|
||||||
* Default: `false`
|
* Default: `false`
|
||||||
* __force_fetchAPI__: forces the use of Fetch API on all browsers that support it
|
* __force_fetchAPI__: forces the use of Fetch API on all browsers that support it
|
||||||
|
@ -180,8 +188,11 @@ Fetch API are used if the following conditions are met:
|
||||||
OR force_fetchAPI is true and the browser supports Fetch API
|
OR force_fetchAPI is true and the browser supports Fetch API
|
||||||
* __overheadCompensationFactor__: compensation for HTTP and network overhead. Default value assumes typical MTUs used over the Internet. You might want to change this if you're using this in your internal network with different MTUs, or if you're using IPv6 instead of IPv4.
|
* __overheadCompensationFactor__: compensation for HTTP and network overhead. Default value assumes typical MTUs used over the Internet. You might want to change this if you're using this in your internal network with different MTUs, or if you're using IPv6 instead of IPv4.
|
||||||
* Default: `1.13359567567567567568` (1048576/925000) assumes HTTP+TCP+IPv4+ETH with typical MTUs used over the Internet
|
* Default: `1.13359567567567567568` (1048576/925000) assumes HTTP+TCP+IPv4+ETH with typical MTUs used over the Internet
|
||||||
* `1460 / 1514`: TCP+IPv4+ETH, ignoring HTTP overhead (this measures the speed at which you actually download/upload files instead of estimating the speed of the connection)
|
* `1.0513`: HTTP+TCP+IPv6+ETH, over the Internet (empirically tested, not calculated)
|
||||||
* `1440 / 1514`: TCP+IPv6+ETH, ignoring HTTP overhead (this measures the speed at which you actually download/upload files instead of estimating the speed of the connection)
|
* `1.0369`: Alternative value for HTTP+TCP+IPv4+ETH, over the Internet (empirically tested, not calculated)
|
||||||
|
* `1460 / 1514`: TCP+IPv4+ETH, ignoring HTTP overhead
|
||||||
|
* `1440 / 1514`: TCP+IPv6+ETH, ignoring HTTP overhead
|
||||||
|
* `1`: ignore overheads. This measures the speed at which you actually download and upload files
|
||||||
|
|
||||||
### Aborting the test prematurely
|
### Aborting the test prematurely
|
||||||
The test can be aborted at any time by sending an abort command to the worker:
|
The test can be aborted at any time by sending an abort command to the worker:
|
||||||
|
@ -194,6 +205,15 @@ This will terminate all network activity and stop the worker.
|
||||||
|
|
||||||
__Important:__ do not simply kill the worker while it's running, as it may leave pending XHR requests!
|
__Important:__ do not simply kill the worker while it's running, as it may leave pending XHR requests!
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
These are the most common issues reported by users, and how to fix them
|
||||||
|
|
||||||
|
#### Download test gives very low result
|
||||||
|
Are garbage.php and empty.php (or your replacements) reachable?
|
||||||
|
Press F12, select network and start the test. Do you see errors? (cancelled requests are not errors)
|
||||||
|
|
||||||
|
#### Upload test is inaccurate, and I see lag spikes
|
||||||
|
Check your server's maximum POST size, make sure it's at least 20Mbytes, possibly more
|
||||||
|
|
||||||
## Using the test without PHP
|
## Using the test without PHP
|
||||||
If your server does not support PHP, or you're using something newer like Node.js, you can still use this test by replacing `garbage.php`, `empty.php` and `getIP.php` with equivalents.
|
If your server does not support PHP, or you're using something newer like Node.js, you can still use this test by replacing `garbage.php`, `empty.php` and `getIP.php` with equivalents.
|
||||||
|
@ -215,7 +235,7 @@ Your replacement must simply respond with a HTTP code 200 and send nothing else.
|
||||||
#### Replacement for `getIP.php`
|
#### Replacement for `getIP.php`
|
||||||
Your replacement must simply respond with the client's IP as plaintext. Nothing fancy.
|
Your replacement must simply respond with the client's IP as plaintext. Nothing fancy.
|
||||||
|
|
||||||
### JS
|
#### JS
|
||||||
You need to start the test with your replacements like this:
|
You need to start the test with your replacements like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -228,6 +248,7 @@ w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_p
|
||||||
* __Chrome:__ high CPU usage from XHR requests with very fast connections (like gigabit).
|
* __Chrome:__ high CPU usage from XHR requests with very fast connections (like gigabit).
|
||||||
For this reason, the test may report inaccurate results if your CPU is too slow. (Does not affect most computers)
|
For this reason, the test may report inaccurate results if your CPU is too slow. (Does not affect most computers)
|
||||||
* __IE11:__ the upload test is not precise on very fast connections
|
* __IE11:__ the upload test is not precise on very fast connections
|
||||||
|
* __IE11:__ the upload test may not work over HTTPS
|
||||||
* __Safari:__ works, but needs more testing and tweaking for very fast connections
|
* __Safari:__ works, but needs more testing and tweaking for very fast connections
|
||||||
|
|
||||||
## Making changes
|
## Making changes
|
||||||
|
@ -241,7 +262,7 @@ To create the minified version, use UglifyJS like this:
|
||||||
uglifyjs -c --screw-ie8 speedtest_worker.js > speedtest_worker.min.js
|
uglifyjs -c --screw-ie8 speedtest_worker.js > speedtest_worker.min.js
|
||||||
```
|
```
|
||||||
|
|
||||||
Pull requests are much appreciated. If you don't use github (or git), simply contact me.
|
Pull requests are much appreciated. If you don't use github (or git), simply contact me at dosse91@paranoici.org.
|
||||||
|
|
||||||
__Important:__ please add your name to modified versions to distinguish them from the main project.
|
__Important:__ please add your name to modified versions to distinguish them from the main project.
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,8 @@
|
||||||
// speedtest cancelled, clear output data
|
// speedtest cancelled, clear output data
|
||||||
data = []
|
data = []
|
||||||
}
|
}
|
||||||
download.textContent = data[1]
|
download.textContent = (status==1&&data[1]==0)?"Starting":data[1]
|
||||||
upload.textContent = data[2]
|
upload.textContent = (status==3&&data[2]==0)?"Starting":data[2]
|
||||||
ping.textContent = data[3]
|
ping.textContent = data[3]
|
||||||
ip.textContent = data[4]
|
ip.textContent = data[4]
|
||||||
jitter.textContent = data[5]
|
jitter.textContent = data[5]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
HTML5 Speedtest v4.2.4
|
HTML5 Speedtest v4.2.5
|
||||||
by Federico Dossena
|
by Federico Dossena
|
||||||
https://github.com/adolfintel/speedtest/
|
https://github.com/adolfintel/speedtest/
|
||||||
GNU LGPLv3 License
|
GNU LGPLv3 License
|
||||||
|
@ -17,6 +17,8 @@ var clientIp = '' // client's IP address as reported by getIP.php
|
||||||
var settings = {
|
var settings = {
|
||||||
time_ul: 15, // duration of upload test in seconds
|
time_ul: 15, // duration of upload test in seconds
|
||||||
time_dl: 15, // duration of download test in seconds
|
time_dl: 15, // duration of download test in seconds
|
||||||
|
time_ulGraceTime: 3, //time to wait in seconds before actually measuring ul speed (wait for buffers to fill)
|
||||||
|
time_dlGraceTime: 1.5, //time to wait in seconds before actually measuring dl speed (wait for TCP window to increase)
|
||||||
count_ping: 35, // number of pings to perform in ping test
|
count_ping: 35, // number of pings to perform in ping test
|
||||||
url_dl: 'garbage.php', // path to a large file or garbage.php, used for download test. must be relative to this js file
|
url_dl: 'garbage.php', // path to a large file or garbage.php, used for download test. must be relative to this js file
|
||||||
url_ul: 'empty.php', // path to an empty file, used for upload test. must be relative to this js file
|
url_ul: 'empty.php', // path to an empty file, used for upload test. must be relative to this js file
|
||||||
|
@ -44,6 +46,11 @@ var interval = null // timer used in tests
|
||||||
*/
|
*/
|
||||||
var useFetchAPI = false
|
var useFetchAPI = false
|
||||||
|
|
||||||
|
/*
|
||||||
|
this function is used on URLs passed in the settings to determine whether we need a ? or an & as a separator
|
||||||
|
*/
|
||||||
|
function url_sep (url) { return url.match(/\?/) ? '&' : '?'; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
listener for commands from main thread to this worker.
|
listener for commands from main thread to this worker.
|
||||||
commands:
|
commands:
|
||||||
|
@ -100,6 +107,8 @@ this.addEventListener('message', function (e) {
|
||||||
if (typeof s.xhr_dlUseBlob !== 'undefined') settings.xhr_dlUseBlob = s.xhr_dlUseBlob // use blob for download test
|
if (typeof s.xhr_dlUseBlob !== 'undefined') settings.xhr_dlUseBlob = s.xhr_dlUseBlob // use blob for download test
|
||||||
if (typeof s.garbagePhp_chunkSize !== 'undefined') settings.garbagePhp_chunkSize = s.garbagePhp_chunkSize // size of garbage.php chunks
|
if (typeof s.garbagePhp_chunkSize !== 'undefined') settings.garbagePhp_chunkSize = s.garbagePhp_chunkSize // size of garbage.php chunks
|
||||||
if (typeof s.force_fetchAPI !== 'undefined') settings.force_fetchAPI = s.force_fetchAPI // use fetch api on all browsers that support it if enabled
|
if (typeof s.force_fetchAPI !== 'undefined') settings.force_fetchAPI = s.force_fetchAPI // use fetch api on all browsers that support it if enabled
|
||||||
|
if (typeof s.time_dlGraceTime !== 'undefined') settings.time_dlGraceTime = s.time_dlGraceTime // dl test grace time before measuring
|
||||||
|
if (typeof s.time_ulGraceTime !== 'undefined') settings.time_ulGraceTime = s.time_ulGraceTime // ul test grace time before measuring
|
||||||
if (typeof s.overheadCompensationFactor !== 'undefined') settings.overheadCompensationFactor = s.overheadCompensationFactor //custom overhead compensation factor (default assumes HTTP+TCP+IP+ETH with typical MTUs)
|
if (typeof s.overheadCompensationFactor !== 'undefined') settings.overheadCompensationFactor = s.overheadCompensationFactor //custom overhead compensation factor (default assumes HTTP+TCP+IP+ETH with typical MTUs)
|
||||||
if (settings.allow_fetchAPI && settings.force_fetchAPI && (!!self.fetch)) useFetchAPI = true
|
if (settings.allow_fetchAPI && settings.force_fetchAPI && (!!self.fetch)) useFetchAPI = true
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
|
@ -137,7 +146,7 @@ function getIp (done) {
|
||||||
xhr.onerror = function () {
|
xhr.onerror = function () {
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
xhr.open('GET', settings.url_getIp + '?r=' + Math.random(), true)
|
xhr.open('GET', settings.url_getIp + url_sep(settings.url_getIp) + 'r=' + Math.random(), true)
|
||||||
xhr.send()
|
xhr.send()
|
||||||
}
|
}
|
||||||
// download test, calls done function when it's over
|
// download test, calls done function when it's over
|
||||||
|
@ -146,6 +155,7 @@ function dlTest (done) {
|
||||||
if (dlCalled) return; else dlCalled = true // dlTest already called?
|
if (dlCalled) return; else dlCalled = true // dlTest already called?
|
||||||
var totLoaded = 0.0, // total number of loaded bytes
|
var totLoaded = 0.0, // total number of loaded bytes
|
||||||
startT = new Date().getTime(), // timestamp when test was started
|
startT = new Date().getTime(), // timestamp when test was started
|
||||||
|
graceTimeDone = false, //set to true after the grace time is past
|
||||||
failed = false // set to true if a stream fails
|
failed = false // set to true if a stream fails
|
||||||
xhr = []
|
xhr = []
|
||||||
// function to create a download stream. streams are slightly delayed so that they will not end at the same time
|
// function to create a download stream. streams are slightly delayed so that they will not end at the same time
|
||||||
|
@ -153,7 +163,7 @@ function dlTest (done) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
if (testStatus !== 1) return // delayed stream ended up starting after the end of the download test
|
if (testStatus !== 1) return // delayed stream ended up starting after the end of the download test
|
||||||
if (useFetchAPI) {
|
if (useFetchAPI) {
|
||||||
xhr[i] = fetch(settings.url_dl + '?r=' + Math.random() + '&ckSize=' + settings.garbagePhp_chunkSize).then(function (response) {
|
xhr[i] = fetch(settings.url_dl + url_sep(settings.url_dl) + 'r=' + Math.random() + '&ckSize=' + settings.garbagePhp_chunkSize).then(function (response) {
|
||||||
var reader = response.body.getReader()
|
var reader = response.body.getReader()
|
||||||
var consume = function () {
|
var consume = function () {
|
||||||
return reader.read().then(function (result) {
|
return reader.read().then(function (result) {
|
||||||
|
@ -192,7 +202,7 @@ function dlTest (done) {
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
// send xhr
|
// send xhr
|
||||||
try { if (settings.xhr_dlUseBlob) xhr[i].responseType = 'blob'; else xhr[i].responseType = 'arraybuffer' } catch (e) { }
|
try { if (settings.xhr_dlUseBlob) xhr[i].responseType = 'blob'; else xhr[i].responseType = 'arraybuffer' } catch (e) { }
|
||||||
xhr[i].open('GET', settings.url_dl + '?r=' + Math.random() + '&ckSize=' + settings.garbagePhp_chunkSize, true) // random string to prevent caching
|
xhr[i].open('GET', settings.url_dl + url_sep(settings.url_dl) + 'r=' + Math.random() + '&ckSize=' + settings.garbagePhp_chunkSize, true) // random string to prevent caching
|
||||||
xhr[i].send()
|
xhr[i].send()
|
||||||
}
|
}
|
||||||
}.bind(this), 1 + delay)
|
}.bind(this), 1 + delay)
|
||||||
|
@ -205,13 +215,23 @@ function dlTest (done) {
|
||||||
interval = setInterval(function () {
|
interval = setInterval(function () {
|
||||||
var t = new Date().getTime() - startT
|
var t = new Date().getTime() - startT
|
||||||
if (t < 200) return
|
if (t < 200) return
|
||||||
var speed = totLoaded / (t / 1000.0)
|
if (!graceTimeDone){
|
||||||
dlStatus = ((speed * 8 * settings.overheadCompensationFactor)/1048576).toFixed(2) // speed is multiplied by 8 to go from bytes to bits, overhead compensation is applied, then everything is divided by 1048576 to go to megabits/s
|
if (t > 1000 * settings.time_dlGraceTime){
|
||||||
if ((t / 1000.0) > settings.time_dl || failed) { // test is over, stop streams and timer
|
if (totLoaded > 0){ // if the connection is so slow that we didn't get a single chunk yet, do not reset
|
||||||
if (failed || isNaN(dlStatus)) dlStatus = 'Fail'
|
startT = new Date().getTime()
|
||||||
clearRequests()
|
totLoaded = 0.0;
|
||||||
clearInterval(interval)
|
}
|
||||||
done()
|
graceTimeDone = true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
var speed = totLoaded / (t / 1000.0)
|
||||||
|
dlStatus = ((speed * 8 * settings.overheadCompensationFactor)/1048576).toFixed(2) // speed is multiplied by 8 to go from bytes to bits, overhead compensation is applied, then everything is divided by 1048576 to go to megabits/s
|
||||||
|
if ((t / 1000.0) > settings.time_dl || failed) { // test is over, stop streams and timer
|
||||||
|
if (failed || isNaN(dlStatus)) dlStatus = 'Fail'
|
||||||
|
clearRequests()
|
||||||
|
clearInterval(interval)
|
||||||
|
done()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.bind(this), 200)
|
}.bind(this), 200)
|
||||||
}
|
}
|
||||||
|
@ -230,9 +250,10 @@ reqsmall = new Blob(reqsmall)
|
||||||
var ulCalled = false // used to prevent multiple accidental calls to ulTest
|
var ulCalled = false // used to prevent multiple accidental calls to ulTest
|
||||||
function ulTest (done) {
|
function ulTest (done) {
|
||||||
if (ulCalled) return; else ulCalled = true // ulTest already called?
|
if (ulCalled) return; else ulCalled = true // ulTest already called?
|
||||||
var totLoaded = 0.0 // total number of transmitted bytes
|
var totLoaded = 0.0, // total number of transmitted bytes
|
||||||
var startT = new Date().getTime() // timestamp when test was started
|
startT = new Date().getTime(), // timestamp when test was started
|
||||||
var failed = false // set to true if a stream fails
|
graceTimeDone = false, //set to true after the grace time is past
|
||||||
|
failed = false // set to true if a stream fails
|
||||||
xhr = []
|
xhr = []
|
||||||
// function to create an upload stream. streams are slightly delayed so that they will not end at the same time
|
// function to create an upload stream. streams are slightly delayed so that they will not end at the same time
|
||||||
var testStream = function (i, delay) {
|
var testStream = function (i, delay) {
|
||||||
|
@ -261,7 +282,7 @@ function ulTest (done) {
|
||||||
delete (xhr[i])
|
delete (xhr[i])
|
||||||
if (settings.xhr_ignoreErrors === 1) testStream(i,100); //restart stream after 100ms
|
if (settings.xhr_ignoreErrors === 1) testStream(i,100); //restart stream after 100ms
|
||||||
}
|
}
|
||||||
xhr[i].open('POST', settings.url_ul + '?r=' + Math.random(), true) // random string to prevent caching
|
xhr[i].open('POST', settings.url_ul + url_sep(settings.url_ul) + 'r=' + Math.random(), true) // random string to prevent caching
|
||||||
xhr[i].setRequestHeader('Content-Encoding', 'identity') // disable compression (some browsers may refuse it, but data is incompressible anyway)
|
xhr[i].setRequestHeader('Content-Encoding', 'identity') // disable compression (some browsers may refuse it, but data is incompressible anyway)
|
||||||
xhr[i].send(reqsmall)
|
xhr[i].send(reqsmall)
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,7 +306,7 @@ function ulTest (done) {
|
||||||
if (settings.xhr_ignoreErrors === 1) testStream(i, 100) //restart stream after 100ms
|
if (settings.xhr_ignoreErrors === 1) testStream(i, 100) //restart stream after 100ms
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
// send xhr
|
// send xhr
|
||||||
xhr[i].open('POST', settings.url_ul + '?r=' + Math.random(), true) // random string to prevent caching
|
xhr[i].open('POST', settings.url_ul + url_sep(settings.url_ul) + 'r=' + Math.random(), true) // random string to prevent caching
|
||||||
xhr[i].setRequestHeader('Content-Encoding', 'identity') // disable compression (some browsers may refuse it, but data is incompressible anyway)
|
xhr[i].setRequestHeader('Content-Encoding', 'identity') // disable compression (some browsers may refuse it, but data is incompressible anyway)
|
||||||
xhr[i].send(req)
|
xhr[i].send(req)
|
||||||
}
|
}
|
||||||
|
@ -299,13 +320,23 @@ function ulTest (done) {
|
||||||
interval = setInterval(function () {
|
interval = setInterval(function () {
|
||||||
var t = new Date().getTime() - startT
|
var t = new Date().getTime() - startT
|
||||||
if (t < 200) return
|
if (t < 200) return
|
||||||
var speed = totLoaded / (t / 1000.0)
|
if (!graceTimeDone){
|
||||||
ulStatus = ((speed * 8 * settings.overheadCompensationFactor)/1048576).toFixed(2) // speed is multiplied by 8 to go from bytes to bits, overhead compensation is applied, then everything is divided by 1048576 to go to megabits/s
|
if (t > 1000 * settings.time_ulGraceTime){
|
||||||
if ((t / 1000.0) > settings.time_ul || failed) { // test is over, stop streams and timer
|
if (totLoaded > 0){ // if the connection is so slow that we didn't get a single chunk yet, do not reset
|
||||||
if (failed || isNaN(ulStatus)) ulStatus = 'Fail'
|
startT = new Date().getTime()
|
||||||
clearRequests()
|
totLoaded = 0.0;
|
||||||
clearInterval(interval)
|
}
|
||||||
done()
|
graceTimeDone = true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
var speed = totLoaded / (t / 1000.0)
|
||||||
|
ulStatus = ((speed * 8 * settings.overheadCompensationFactor)/1048576).toFixed(2) // speed is multiplied by 8 to go from bytes to bits, overhead compensation is applied, then everything is divided by 1048576 to go to megabits/s
|
||||||
|
if ((t / 1000.0) > settings.time_ul || failed) { // test is over, stop streams and timer
|
||||||
|
if (failed || isNaN(ulStatus)) ulStatus = 'Fail'
|
||||||
|
clearRequests()
|
||||||
|
clearInterval(interval)
|
||||||
|
done()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.bind(this), 200)
|
}.bind(this), 200)
|
||||||
}
|
}
|
||||||
|
@ -330,7 +361,7 @@ function pingTest (done) {
|
||||||
} else {
|
} else {
|
||||||
var instspd = (new Date().getTime() - prevT)
|
var instspd = (new Date().getTime() - prevT)
|
||||||
var instjitter = Math.abs(instspd - prevInstspd)
|
var instjitter = Math.abs(instspd - prevInstspd)
|
||||||
if (i === 1) ping = instspd; /* first ping, can't tell jiutter yet*/ else {
|
if (i === 1) ping = instspd; /* first ping, can't tell jitter yet*/ else {
|
||||||
ping = ping * 0.9 + instspd * 0.1 // ping, weighted average
|
ping = ping * 0.9 + instspd * 0.1 // ping, weighted average
|
||||||
jitter = instjitter > jitter ? (jitter * 0.2 + instjitter * 0.8) : (jitter * 0.9 + instjitter * 0.1) // update jitter, weighted average. spikes in ping values are given more weight.
|
jitter = instjitter > jitter ? (jitter * 0.2 + instjitter * 0.8) : (jitter * 0.9 + instjitter * 0.1) // update jitter, weighted average. spikes in ping values are given more weight.
|
||||||
}
|
}
|
||||||
|
@ -351,13 +382,13 @@ function pingTest (done) {
|
||||||
}
|
}
|
||||||
if (settings.xhr_ignoreErrors === 1) doPing() //retry ping
|
if (settings.xhr_ignoreErrors === 1) doPing() //retry ping
|
||||||
|
|
||||||
if(settings.xhr_ignoreErrors === 2){ //ignore failed ping
|
if (settings.xhr_ignoreErrors === 2){ //ignore failed ping
|
||||||
i++
|
i++
|
||||||
if (i < settings.count_ping) doPing(); else done() // more pings to do?
|
if (i < settings.count_ping) doPing(); else done() // more pings to do?
|
||||||
}
|
}
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
// sent xhr
|
// sent xhr
|
||||||
xhr[0].open('GET', settings.url_ping + '?r=' + Math.random(), true) // random string to prevent caching
|
xhr[0].open('GET', settings.url_ping + url_sep(settings.url_ping) + 'r=' + Math.random(), true) // random string to prevent caching
|
||||||
xhr[0].send()
|
xhr[0].send()
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
doPing() // start first ping
|
doPing() // start first ping
|
||||||
|
|
2
speedtest_worker.min.js
vendored
2
speedtest_worker.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue