Skip to content
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

feat(predictive-perf): add shell and base audit #2720

Merged
merged 3 commits into from
Sep 1, 2017
Merged

Conversation

patrickhulce
Copy link
Collaborator

@patrickhulce patrickhulce commented Jul 21, 2017

in the name of FastMode #2703

The first commit introduces the primary structure of how the estimates will be computed.

  • audits/predictive-perf.js - file where a dependency graph is requested, subgraphs will be created and estimates combined
  • gather/computed/page-dependency-graph.js - main file responsible for creating dependency graphs and measuring their execution time, heavily leverages the logic of graph nodes found in ./dependency-graph
  • gather/computed/dependency-graph/* - folder where different resource/task types will be added

For easier reviewing I've split out the bulk of the logic that was here into three other PRs: #3187 #3162 #3163

const trace = artifacts.traces[Audit.DEFAULT_PASS];
const devtoolsLogs = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
return artifacts.requestPageDependencyGraph(trace, devtoolsLogs).then(graph => {
const rawValue = PageDependencyGraph.computeGraphDuration(graph);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will eventually be the blending of multiple graph durations

*/
'use strict';

class Node {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other resource types will extend this base class

return [];
}

static createGraph(traceOfTab, networkRecords) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method will eventually create different node types and link them in a more sophisticated way, for now it's just linking most basic initiator properties of network records

return rootNode;
}

static computeGraphDuration(rootNode) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method will eventually do more browser emulation with tcp connections and main thread execution but for now it just finds the maximumal request chain and assumes a single hop

}

static getNetworkInitiators(record) {
if (!record._initiator) return [];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revisit using initiatorRequest when I flesh this out, but for now I was getting cyclic dependencies on certain runs

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking pretty cool.

Quick driveby: it would be great to get some jsdocs so e.g. inputs/outputs are more obvious locally :)

@patrickhulce
Copy link
Collaborator Author

it would be great to get some jsdocs

I made a bet with myself if I would get structural feedback or missing jsdoc comments first 😆

@patrickhulce patrickhulce changed the title feat: add predictive perf shell feat: add predictive perf Aug 1, 2017
@patrickhulce patrickhulce force-pushed the predictive_perf branch 2 times, most recently from 7295761 to c34c085 Compare August 18, 2017 00:12
@patrickhulce patrickhulce force-pushed the predictive_perf branch 2 times, most recently from 7bb2916 to 6e90985 Compare August 21, 2017 22:31
@patrickhulce
Copy link
Collaborator Author

PTAL :)

@patrickhulce patrickhulce changed the title feat: add predictive perf feat(predictive-perf): add shell and base audit Aug 30, 2017
* @param {!WebInspector.NetworkRequest} record
* @return {!Array<string>}
*/
static getNetworkInitiators(record) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out https://cs.chromium.org/chromium/src/tools/android/loading/request_dependencies_lens.py?type=cs&q=f:request_dependencies_lens+_GetDependency

The logic for redirect and parser requests seem worthwhile.

The script case handles a lot of edge cases that might be worth using.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this is great!! wdyt about making these changes on top of #3163 to reflect the incremental improvements?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm.


describe('#computeGraphDuration', () => {
it('should compute graph duration', () => {
// B - C - D - E - F
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it'd be really handy to get a visualization of these graphs to help debug. What did you use while developing this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the printGraph function of PageDependencyGraph computed artifact came in crazy handy early, but mostly a lot of --inspect-brk once the cases got more complicated

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tight. that's over in #3162 . thx

@@ -258,7 +258,7 @@ class Runner {
const computedArtifacts = {};
require('fs').readdirSync(__dirname + '/gather/computed').forEach(function(filename) {
// Skip base class.
if (filename === 'computed-artifact.js') return;
if (filename === 'computed-artifact.js' || filename.startsWith('dependency-graph')) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be 'dependency-graph/' maybe? It took me a while to realize this was talking about the directory path rather than the start of a filename

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh ya sure that's clearer 👍

return {
category: 'Performance',
name: 'predictive-perf',
description: 'Predicted Performance (beta)',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry but you need a failureDescription and non-empty helpText. :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh, yeah i'll cherry-pick from the future 🤖

* @param {!WebInspector.NetworkRequest} record
* @return {!Array<string>}
*/
static getNetworkInitiators(record) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm.

}

const maxDepth = getMax(depthByNodeId.values());
return maxDepth * Emulation.settings.TYPICAL_MOBILE_THROTTLING_METRICS.latency;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structure-wise I feel like it'd be a tad better to have this be a generic graph computeMaxDepth method.

Optionally, I could see this latency work going into the audit rather than here in the graph computed artifact.

You are now telling me verbally that this all disappears in the next commit... so.... 💨 💨 💨 💨

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

* node that was called clone is not included in the resulting filtered graph, the return will be
* undefined.
* @param {function(!Node):boolean=} predicate
* @return {?Node}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want {!Node|undefined} (unless it can also be null)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup you're right 👍 fixed

*/
'use strict';

class Node {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add some additional description on the invariants in how it's used? Esp multiple dependencies but single root node

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg

@patrickhulce patrickhulce merged commit f473118 into master Sep 1, 2017
@patrickhulce patrickhulce deleted the predictive_perf branch September 1, 2017 16:15
thisizkp pushed a commit to thisizkp/lighthouse that referenced this pull request Sep 2, 2017
* feat(predictive-perf): add shell and base audit

* address feedback

* add invariant comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants