diff --git a/README.md b/README.md index 1d4e16f..66448c8 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,12 @@ image format. Sources: https://github.com/webmproject/libwebp-demo/tree/gh-pages/webp_js - ## Decoding timing test [android_timing_test/](https://github.com/webmproject/libwebp-demo/tree/master/android_webp_test) contains a script to measure the decoding speed on Android devices. ## Battery usage test -[demos/battery/](https://github.com/webmproject/libwebp-demo/tree/master/demos/battery) contains a script to measure the battery consumption when repeatingly decoding an image (WebP, JPEG, ...). +[battery](https://webmproject.github.io/libwebp-demo/battery/index.html) contains a script to measure the battery consumption when repeatingly decoding an image (WebP, JPEG, ...). + +Sources: https://github.com/webmproject/libwebp-demo/tree/gh-pages/battery diff --git a/demos/battery/README.md b/demos/battery/README.md deleted file mode 100644 index 55946c3..0000000 --- a/demos/battery/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# WebP Battery test - -A battery test experiment. This demo uses the [Battery Status API](https://w3c.github.io/battery/) and decodes as many JPEG or WebP images as possible within a given (preset) battery drop. Hence, this test focuses on battery performance rather than speed. - -Use the edit icon on the top right to modify the settings, and start button to run the experiment. - -The UI is built with [PaperGUI](http://google.github.io/paper-gui). diff --git a/demos/battery/css/style.css b/demos/battery/css/style.css deleted file mode 100644 index dbcbb36..0000000 --- a/demos/battery/css/style.css +++ /dev/null @@ -1,53 +0,0 @@ -body { - background: #1d1f20; -} - -a { - color: #2196f3; -} - -table { - margin: 24px 24px 0 0; - padding: 12px; - line-height: 24px; - min-width: 290px; - color: white; - background-color: rgba(0,0,0,.5); - border-radius: 2px; -} - -td:nth-child(2) { - padding-left: 12px; - min-width: 110px; - text-align: right; -} - -.ui { - position: fixed; - top: 24px; - left: 24px; -} - -#btn { - height: 54px; - padding: 0 24px; - border: none; - background-color: white; - color: #ff8507; - text-transform: uppercase; - border-radius: 2px; - box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2); -} - -.paper-gui-0 #fab.paper-gui { - top: 24px; - right: 24px; -} - -.copyme { - position: absolute; - top: 0; - left: 0; - transform: scale(0); - opacity: 0; -} diff --git a/demos/battery/index.html b/demos/battery/index.html deleted file mode 100644 index e77718a..0000000 --- a/demos/battery/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - WebP Battery test experiment - - - - - - - - -
- - - -
- Hello there, welcome to this battery performance test. Battery API is required for this test and might not be around for very long. -

Press Start to run the test, or use the orange button to fiddle with the parameters. To reduce noise, make sure to test over a large-enough battery drain threshold (default is 5%).

-
-
- - - - - diff --git a/demos/battery/js/index.js b/demos/battery/js/index.js deleted file mode 100644 index a28fb23..0000000 --- a/demos/battery/js/index.js +++ /dev/null @@ -1,248 +0,0 @@ -// List of preset test images. CORS must be enabled for these resources. -var images = { - 'WebP 600 x 800 px': 'https://www.gstatic.com/webp/measurement/example1.webp', - 'WebP 800 x 533 px': 'https://www.gstatic.com/webp/measurement/example2.webp', - 'WebP 1200 x 800 px': 'https://www.gstatic.com/webp/measurement/example3.webp', - 'JPEG 600 x 800 px': 'https://www.gstatic.com/webp/measurement/example1.jpg', - 'JPEG 800 x 533 px': 'https://www.gstatic.com/webp/measurement/example2.jpg', - 'JPEG 1200 x 800 px': 'https://www.gstatic.com/webp/measurement/example3.jpg', -}; - -// Experiment configuration parameters. -var params = { - showInfo: true, - presetUrl: images['WebP 600 x 800 px'], - customUrl: '', - batteryDrop: 5 -}; - -// Public variables. -var counter = 0; -var running = false; -var timings, fetchPromise, once; -var stats = {}; -var infoEl = document.getElementById('info'); -var imageEl = document.getElementById('image'); - -// Clears the stats object and fetch counter. -function resetStats() { - stats = {}; - counter = 0; - imageEl.src = ''; - updateInfo(); -}; - -// Renders the stats object as an HTML table. -function updateInfo() { - if (!params.showInfo) { - infoEl.style.display = 'none'; - return; - } - var tableData = {}; - - if (stats.currentBatt && stats.initialBatt) { - tableData['Battery level (at start)'] = Math.floor(stats.currentBatt * 100) - + '% (' + Math.floor(stats.initialBatt * 100) + '%)'; - } - if (stats.fileSize && stats.mime) { - tableData['File info'] = stats.mime + ', ' - + Math.round(stats.fileSize / 1000) + ' Kb'; - } - tableData['Fetch count'] = counter; - if (stats.batt && stats.batt.length) { - tableData['Images/batt.% (avg)'] = stats.batt[stats.batt.length - 1] + ' (' - + Math.round(average(stats.batt)) + ')'; - } - if (stats.fetch && stats.fetch.length) { - tableData['Fetch time (avg)'] = stats.fetch[stats.fetch.length - 1] - + ' ms (' + Math.round(average(stats.fetch)) + ' ms)'; - } - if (stats.load && stats.load.length) { - tableData['Load time (avg)'] = stats.load[stats.load.length - 1] + ' ms (' - + Math.round(average(stats.load)) + ' ms)'; - } - - var html = ''; - Object.keys(tableData).forEach(function(key) { - html += '' + key + '' + tableData[key] + ''; - }); - window.requestAnimationFrame(function() { - infoEl.innerHTML = html; - infoEl.style.display = ''; - }); -} - -// Downloads an image by URL via fetch API, storing some stats in the process, -// and renders it to the DOM via createObjectURL. -var doFetch = function(url) { - if (fetchPromise) { - return; - } - timings = { - fetchStart: Date.now() - }; - fetchPromise = fetch(url) - .then(function(response) { - timings.fetchEnd = Date.now(); - return response.blob(); - }, function(e) { - alert('Unable to fetch the image. Either the URL is incorrect' - + ' or the file has no Access-Control-Allow-Origin header.'); - stop(); - fetchPromise = null; - }) - .then(function(imageBlob) { - fetchPromise = null; - if (!imageBlob || imageBlob.type.indexOf('image/') < 0) { - alert('Woops, fetched file is not an image!'); - stop(); - return; - } - stats.mime = imageBlob.type.replace('image/', ''); - stats.fileSize = imageBlob.size; - URL.revokeObjectURL(imageEl.src); - var objectURL = URL.createObjectURL(imageBlob); - timings.loadStart = Date.now(); - imageEl.src = objectURL; - counter++; - }); - -}; - -// Fetches the next image or shows test results if the loop was interrupted. -var fetchNext = function(opt_manual) { - once = !!opt_manual; - if (!running && !opt_manual) { - alert('Test complete!\n\nImages loaded: ' + counter - + (stats.batt && stats.batt.length ? '\nImages/batt.%: ' - + Math.round(average(stats.batt)) : '\nNo battery stats.')); - return; - } - var url = params.customUrl || params.presetUrl; - doFetch(url + '?ts=' + Date.now()); -}; - -// Image element load callback. Tracks timings and triggers the next fetch. -imageEl.onload = function() { - var loadEnd = Date.now(); - if (!stats.fetch) { - stats.fetch = []; - stats.load = []; - } - stats.fetch.push(timings.fetchEnd - timings.fetchStart); - stats.load.push(loadEnd - timings.loadStart); - updateInfo(); - !once && fetchNext(); - once = false; -}; - -// Interrupts the fetch loop. -function stop() { - running = false; - document.getElementById('btn').innerText = 'Start'; -} - -// Callback for the start/stop button. Runs or interrupts the fetch loop. -function startStop() { - if (running) { - stop(); - return; - } - var start = function() { - document.getElementById('btn').innerText = 'Stop'; - running = true; - fetchNext(); - } - if (navigator.getBattery) { - navigator.getBattery().then(function(battery) { - stats.initialBatt = stats.currentBatt = battery.level; - if (battery.charging) { - alert('Device is currently charging, the test will likely run until' - + ' you stop it manually.'); - } - start(); - }); - } else { - alert('Device doesn\'t support battery API, you\'ll have to manually stop' - + ' the test.'); - start(); - } -}; - -// Battery level change handler. Logs the fetched images count per dropped %. -function batteryChangeHandler(level) { - if (running && !!stats.initialBatt) { - if (!stats.batt) { - stats.batt = []; - } - if (stats.batt.length > 0) { - stats.batt.push( - counter - stats.batt.reduce(function(a, b) { - return a + b; - })); - } else if (stats.initialBatt - level < 0.02) { - // First battery level log. We skip the first percent drop because - // it was probably not entirely consumed by the test and would skew - // the stats. - stats.firstPercentDrop = counter; - } else { - // First entry in the batt stats (count of images for the first full - // percent drop). - stats.batt.push(counter - stats.firstPercentDrop); - } - if ((stats.initialBatt - level) >= params.batteryDrop / 100) { - stop(); - } - } - stats.currentBatt = level; - updateInfo(); -} - -// Monitors battery level changes. -if (navigator.getBattery) { - navigator.getBattery().then(function(battery) { - battery.onlevelchange = function() { - batteryChangeHandler(battery.level); - }; - }); -}; - -// Utility function. -function average(arr) { - return arr.reduce((a, b) => a + b) / arr.length; -}; - -// Build the GUI. -var gui = new PaperGUI(); -gui.add(params, 'showInfo').name('Show stats (uses more battery)') - .onChange(updateInfo); -gui.add(params, 'batteryDrop').min(2).name('Stop test after battery drop (%)'); -gui.add(params, 'presetUrl', images).name('Target image').onChange(stop); -gui.add(params, 'customUrl').name('Custom image URL').onChange(stop); -params.test = function() { - !running && fetchNext(true); -}; -gui.add(params, 'test').name('Test image load'); -params.reset = function() { - resetStats(); -}; -gui.add(params, 'reset').name('Reset stats'); - -// Bonus feature: export stats object to clipboard. -if (document.queryCommandSupported('copy')) { - params.copyStats = function() { - window.getSelection().removeAllRanges(); - var textContainerEl = document.querySelector('.copyme'); - textContainerEl.value = JSON.stringify(stats); - var range = document.createRange(); - range.selectNode(textContainerEl); - window.getSelection().addRange(range); - try { - var successful = document.execCommand('copy'); - alert(successful ? 'Stats have been copied to your clipboard as a JSON string.' : 'Copy command failed!'); - } catch(e) { - alert('Woops. Clouldn\'t copy the data to the clipboard!' + e); - } - }; - gui.add(params, 'copyStats').name('Export stats'); -}