-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plots: make measure script more flexible (CLI args) #2183
Conversation
lighthouse-core/lib/emulation.js
Outdated
@@ -41,10 +41,13 @@ const NEXUS5X_USERAGENT = { | |||
'(KHTML, like Gecko) Chrome/59.0.3033.0 Mobile Safari/537.36' | |||
}; | |||
|
|||
const LATENCY_FACTOR = 3.75; | |||
const THROUGHPUT_FACTOR = 1.1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should we model both of these as multipliers so it's just multiply for both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1.
it's equal to throughput * 90/99
but you might as well simplify it to throughput * 0.9
plots/measure.js
Outdated
}; | ||
console.log('Running lighthouse with flag\n disableNetworkThrottling: ', FLAGS.disableNetworkThrottling); | ||
|
||
const SUBSET = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
running plots/ this weekend, it was very handy to split this to loading from file so I could quickly switch between a couple of different sets of test sites. If you're adding yargs
anyways, it would be great to support loading a list of URLs from a path passed in as a CLI option :)
plots/measure.js
Outdated
@@ -150,20 +178,30 @@ main(); | |||
* Returns a promise chain that analyzes all the sites n times. | |||
* @return {!Promise} | |||
*/ | |||
function runAnalysis() { | |||
function runAnalysisWithNewChromeInstances() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
is this ready to review? And will need a rebase with recent changes to chromeLauncher |
was that a yes? :) |
ping @brendankenny for a review :) |
will need a rebase :) |
plots/measure.js
Outdated
.catch(err => console.error(err)) | ||
.then(() => launcher.kill()); | ||
if (REUSE_CHROME) { | ||
ChromeLauncher.launch({port: 9222}).then(launcher => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been running multiple plots at a time recently.. Launcher is getting a unique port by default, but you have to get it off launcher.port
and pass into lighthouse()
.. Here's what I did today:
Can you support this functionality? You could just pass it along like this or create measure instances that hold this state.. wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yar. Done.
plots/measure.js
Outdated
// Running it n + 1 times if the first run is deliberately ignored | ||
// because it has different perf characteristics from subsequent runs | ||
// (e.g. DNS cache which can't be easily reset between runs) | ||
const NUMBER_OF_RUNS = (CUSTOM_NUMBER_OF_RUNS || 20) + (KEEP_FIRST_RUN ? 0 : 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't seem like an uppercase const as its super conditional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
plots/measure.js
Outdated
@@ -31,9 +59,29 @@ const ChromeLauncher = require('../chrome-launcher/chrome-launcher.js'); | |||
const Printer = require('../lighthouse-cli/printer'); | |||
const assetSaver = require('../lighthouse-core/lib/asset-saver.js'); | |||
|
|||
const NUMBER_OF_RUNS = 20; | |||
const DISABLE_DEVICE_EMULATION = args['disable-device-emulation']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh seems kinda odd to establish these all as uppercase consts as they are dependent on CLI input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah - I removed them and just inlined their usage
plots/measure.js
Outdated
} | ||
|
||
if (SUBSET) { | ||
return [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about we just slice the top of the full sites list instead of repeating here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not DRY but I wanted to both have a set of sites that were useful for cpu/network analysis (basically the most visible / meaningful sites) and preserve the original order of the sites list since it explains in comments how they were sourced.
plots/measure.js
Outdated
// Running it n + 1 times if the first run is deliberately ignored | ||
// because it has different perf characteristics from subsequent runs | ||
// (e.g. DNS cache which can't be easily reset between runs) | ||
const NUMBER_OF_RUNS = (CUSTOM_NUMBER_OF_RUNS || 20) + (KEEP_FIRST_RUN ? 0 : 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's unexpected that number_of_runs == 1 will provide two runs for each site. Can we make sure the number here will match # of actual runs done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - I updated it so there's no +1 run. I added a check in main
so users don't accidentally try to only do 1 run whose results are discard.
plots/utils.js
Outdated
/** | ||
* @param {string} filePath | ||
*/ | ||
function removeRecursive(filePath) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oy - yeah I was using it in a one-off script. I'll remove it.
…nto network-analysis
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please take another look! Sorry this took a while :)
plots/measure.js
Outdated
@@ -31,9 +59,29 @@ const ChromeLauncher = require('../chrome-launcher/chrome-launcher.js'); | |||
const Printer = require('../lighthouse-cli/printer'); | |||
const assetSaver = require('../lighthouse-core/lib/asset-saver.js'); | |||
|
|||
const NUMBER_OF_RUNS = 20; | |||
const DISABLE_DEVICE_EMULATION = args['disable-device-emulation']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah - I removed them and just inlined their usage
plots/measure.js
Outdated
// Running it n + 1 times if the first run is deliberately ignored | ||
// because it has different perf characteristics from subsequent runs | ||
// (e.g. DNS cache which can't be easily reset between runs) | ||
const NUMBER_OF_RUNS = (CUSTOM_NUMBER_OF_RUNS || 20) + (KEEP_FIRST_RUN ? 0 : 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
plots/measure.js
Outdated
// Running it n + 1 times if the first run is deliberately ignored | ||
// because it has different perf characteristics from subsequent runs | ||
// (e.g. DNS cache which can't be easily reset between runs) | ||
const NUMBER_OF_RUNS = (CUSTOM_NUMBER_OF_RUNS || 20) + (KEEP_FIRST_RUN ? 0 : 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - I updated it so there's no +1 run. I added a check in main
so users don't accidentally try to only do 1 run whose results are discard.
plots/measure.js
Outdated
} | ||
|
||
if (SUBSET) { | ||
return [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not DRY but I wanted to both have a set of sites that were useful for cpu/network analysis (basically the most visible / meaningful sites) and preserve the original order of the sites list since it explains in comments how they were sourced.
plots/measure.js
Outdated
.catch(err => console.error(err)) | ||
.then(() => launcher.kill()); | ||
if (REUSE_CHROME) { | ||
ChromeLauncher.launch({port: 9222}).then(launcher => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yar. Done.
plots/utils.js
Outdated
/** | ||
* @param {string} filePath | ||
*/ | ||
function removeRecursive(filePath) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oy - yeah I was using it in a one-off script. I'll remove it.
plots/measure.js
Outdated
* then open a fresh Chrome instance for each run. | ||
*/ | ||
function getUrls() { | ||
if (args['sites-path']) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we already have this, why not toss the default SITES into a file and have sites-path default to that one.
plots/measure.js
Outdated
} | ||
|
||
if (args['subset']) { | ||
return [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and it seems like we could just extract this into a diff sites_subset.js file?
function analyzeWithLighthouse(url, outputPath, assetsPath, {ignoreRun}) { | ||
const flags = {output: 'json'}; | ||
function analyzeWithLighthouse(launcher, url, outputPath, assetsPath, {ignoreRun}) { | ||
const flags = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ignoreRun is true then there's no reason to have throttling on. I'd force disable cpu & network throttling in these cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yo @paulirish - updated per your comments.
function analyzeWithLighthouse(url, outputPath, assetsPath, {ignoreRun}) { | ||
const flags = {output: 'json'}; | ||
function analyzeWithLighthouse(launcher, url, outputPath, assetsPath, {ignoreRun}) { | ||
const flags = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
plots/sites.js
Outdated
'use strict'; | ||
|
||
/* eslint-disable no-unused-expressions */ | ||
[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module.exports = [
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
plots/sites_subset.js
Outdated
'use strict'; | ||
|
||
/* eslint-disable no-unused-expressions */ | ||
[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module.exports = [
...
plots/measure.js
Outdated
'https://ask.com', | ||
'https://bbc.com' | ||
]; | ||
const keepFirstRun = args['keep-first-run'] || !args['reuse-chrome']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use camelcase instead of this square bracket dance.
args.keepFirstRun
etc. yargs does it for you.
plots/measure.js
Outdated
return eval(fs.readFileSync(path.resolve(__dirname, 'sites_subset.js'), 'utf-8')); | ||
} | ||
|
||
return eval(fs.readFileSync(path.resolve(__dirname, 'sites.js'), 'utf-8')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead. you can set the default on yargs:
.default('sites-path', 'sites.js')
plots/measure.js
Outdated
} | ||
|
||
if (args['sites-path']) { | ||
const sitesPath = path.resolve(__dirname, args['sites-path']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (args.sitesPath) {
return require(path.resolve(__dirname, args.sitesPath));
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah - this is nice. I did it the more verbose way because the downside is require() will hold onto these files indefinitely in node's module cache. It's definitely OK now since the sites list are needed for the entire lifetime of the script but if we start loading a lot of different sites files, we'll need to watch out for heap usage.
@paulirish - please take another look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm % nits
thanks! excited about this
plots/measure.js
Outdated
}) | ||
.group( | ||
['disable-device-emulation', 'disable-cpu-throttling', 'disable-network-throttling'], | ||
'Chrome DevTools settings:') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's call this Lighthouse settings:
plots/measure.js
Outdated
@@ -17,11 +17,40 @@ | |||
'use strict'; | |||
|
|||
/* eslint-disable no-console */ | |||
|
|||
const fs = require('fs'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer neccessary
plots/measure.js
Outdated
'https://bbc.com' | ||
]; | ||
const keepFirstRun = args.keepFirstRun || !args.reuseChrome; | ||
const numberOfRuns = args.n || 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move to yargs default
plots/plot-per-site.html
Outdated
<script src="https://cdn.plot.ly/plotly-1.25.2.min.js"></script> | ||
</head> | ||
|
||
<body> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add this page to the <nav>
of the other two html files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
plots/plot-per-site.html
Outdated
@@ -0,0 +1,29 @@ | |||
<!-- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename this to bars-per-site ?
const path = require('path'); | ||
const parseURL = require('url').parse; | ||
|
||
const mkdirp = require('mkdirp'); | ||
const args = require('yargs') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with the new style of invoking, can you update the readme?
to me, it makes more sense to use the node script.js
invocation rather than the npm run
one now that we have a CLI. but no big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed it up!
plots/plot-per-site.html
Outdated
<script src="https://cdn.plot.ly/plotly-1.25.2.min.js"></script> | ||
</head> | ||
|
||
<body> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
# Run lighthouse to collect metrics data | ||
$ yarn measure | ||
$ node measure.js |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you got a whole CLI for measure.js now!. at the very least you should paste the --help
output into the readme
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice stuff all around! Thanks for the back 'n forth!
📉 📈 📊
Add flags, help docs, and making it better all around.