diff --git a/.gitignore b/.gitignore index 8d4ae25..1e501e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ bower_components +node_modules \ No newline at end of file diff --git a/node-perf-tester.js b/node-perf-tester.js new file mode 100644 index 0000000..03ce432 --- /dev/null +++ b/node-perf-tester.js @@ -0,0 +1,93 @@ +const path = require('path'); + +const CDP = require('chrome-remote-interface'); + +const argv = require('minimist')(process.argv.slice(2)); + +const NUMBER_OF_RUNS = argv.runs || 100; + +(async function() { + let port = argv.port; + let chrome; + + if (!argv.port) { + const chromeLauncher = require('chrome-launcher'); + chrome = await chromeLauncher.launch({ + chromeFlags: ['--headless', '--disable-gpu', '--remote-debugging-address=0.0.0.0'], + port: 0 + }); + port = chrome.port; + } + + const tab = await CDP.New({port}); + const client = await CDP({tab, port}); + + const {Page, Network, Runtime} = client; + + const ONE_MB = 1024 * 1024 / 8; + const throttling = { + FAST_3G: { + downloadThroughput: 1.6 * ONE_MB * .9, + uploadThroughput: .75 * ONE_MB * .9 + }, + SLOW_3G: { + downloadThroughput: .5 * ONE_MB * .8, + uploadThroughput: .5 * ONE_MB * .8 + } + } + + await Promise.all([ + Page.enable(), + Network.enable(), + port && argv.throttling && Network.emulateNetworkConditions( + Object.assign({}, throttling[argv.throttling], { + offline: false, + latency: 10 + }) + ), + Network.clearBrowserCache(), + Network.setCacheDisabled({cacheDisabled: true}), + Network.setBypassServiceWorker({bypass: true}), + ]); + + let loadEventPromise; + + Page.loadEventFired(() => { + loadEventPromise(); + }); + + const options = require(path.join(process.cwd(), argv.targets)); + + const perfTimings = {}; + for (const [type] of options) { + perfTimings[type] = []; + } + + process.on('exit', async() => { + for (const [type, timings] of Object.entries(perfTimings)) { + const average = timings.reduce((a, b) => a + b) / timings.length; + console.log(`Average gain for ${type} in ${timings.length} runs is ${average}`); + } + + await CDP.Close({port, id: tab.id}); + await client.close(); + if (!argv.port) { + await chrome.kill(); + } + }); + + for (let i = 0; i < NUMBER_OF_RUNS; i++) { + for (const [type, url] of options) { + requestType = type; + + Page.navigate({url}); + + await new Promise(resolve => { + loadEventPromise = resolve; + }); + const {result: {value: perfTiming}} = await Runtime.evaluate({expression: 'window.perfTiming'}); + perfTimings[type].push(perfTiming); + } + process.stdout.write(`${i + 1}/${NUMBER_OF_RUNS}\r`); + } +})() \ No newline at end of file diff --git a/options.json b/options.json new file mode 100644 index 0000000..2c1f787 --- /dev/null +++ b/options.json @@ -0,0 +1,4 @@ +[ + ["original", "http://localhost:8081/youtube/"], + ["effects", "http://localhost:8081/youtube/index-effects.html"] +] \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0f38055 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "perf-tester", + "version": "0.0.1", + "main": "node-perf-tester.js", + "license": "BSD-3-Clause", + "dependencies": { + "chrome-launcher": "^0.4.0", + "chrome-remote-interface": "^0.24.3", + "minimist": "^1.2.0" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..591d7d7 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,144 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/core-js@^0.9.41": + version "0.9.42" + resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-0.9.42.tgz#dd6da92cd7d5ab5ca0b4477524537c3e633b6bce" + +"@types/mkdirp@^0.3.29": + version "0.3.29" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.3.29.tgz#7f2ad7ec55f914482fc9b1ec4bb1ae6028d46066" + +"@types/node@6.0.66": + version "6.0.66" + resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.66.tgz#5680b74a6135d33d4c00447e7c3dc691a4601625" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +chrome-launcher@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chrome-launcher/-/chrome-launcher-0.4.0.tgz#805e4a90d3d16c93655216aeba1fe880922ecc1f" + dependencies: + "@types/core-js" "^0.9.41" + "@types/mkdirp" "^0.3.29" + "@types/node" "6.0.66" + lighthouse-logger "^1.0.0" + mkdirp "0.5.1" + rimraf "^2.6.1" + +chrome-remote-interface@^0.24.3: + version "0.24.3" + resolved "https://registry.yarnpkg.com/chrome-remote-interface/-/chrome-remote-interface-0.24.3.tgz#ee38252fd43bea435dd1dbb74f4b90d179186bc9" + dependencies: + commander "2.1.x" + ws "2.0.x" + +commander@2.1.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +debug@^2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +glob@^7.0.5: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +lighthouse-logger@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.0.0.tgz#c6abdfbbbf0b4a541ab33864802cbad8944bcc8c" + dependencies: + debug "^2.6.8" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +rimraf@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +ultron@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +ws@2.0.x: + version "2.0.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-2.0.3.tgz#532fd499c3f7d7d720e543f1f807106cfc57d9cb" + dependencies: + ultron "~1.1.0"