Skip to content

Commit

Permalink
fix(predictive-perf): split CPU and Layout task multipliers
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce committed Sep 25, 2017
1 parent f68cfe1 commit 0ff9ef9
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ const emulation = require('../../../../lib/emulation').settings;

// see https://cs.chromium.org/search/?q=kDefaultMaxNumDelayableRequestsPerClient&sq=package:chromium&type=cs
const DEFAULT_MAXIMUM_CONCURRENT_REQUESTS = 10;

// Fast 3G emulation target from DevTools, WPT 3G - Fast setting
const DEFAULT_FALLBACK_TTFB = 30;
const DEFAULT_RTT = emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetLatency;
const DEFAULT_THROUGHPUT = emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetDownloadThroughput * 8;
const DEFAULT_CPU_MULTIPLIER = 5;
const DEFAULT_THROUGHPUT = emulation.TYPICAL_MOBILE_THROTTLING_METRICS.targetDownloadThroughput * 8; // 1.6 Mbps

// same multiplier as Lighthouse uses for CPU emulation
const DEFAULT_CPU_TASK_MULTIPLIER = 4;
// layout tasks tend to be less CPU-bound and do not experience the same increase in duration
const DEFAULT_LAYOUT_TASK_MULTIPLIER = 2;
// if a task takes more than 10 seconds it's usually a sign it isn't actually CPU bound and we're over estimating
const DEFAULT_MAXIMUM_CPU_TASK_DURATION = 10000;

const TLS_SCHEMES = ['https', 'wss'];

Expand Down Expand Up @@ -44,7 +52,8 @@ class Estimator {
throughput: DEFAULT_THROUGHPUT,
fallbackTTFB: DEFAULT_FALLBACK_TTFB,
maximumConcurrentRequests: DEFAULT_MAXIMUM_CONCURRENT_REQUESTS,
cpuMultiplier: DEFAULT_CPU_MULTIPLIER,
cpuTaskMultiplier: DEFAULT_CPU_TASK_MULTIPLIER,
layoutTaskMultiplier: DEFAULT_LAYOUT_TASK_MULTIPLIER,
},
options
);
Expand All @@ -56,7 +65,8 @@ class Estimator {
TcpConnection.maximumSaturatedConnections(this._rtt, this._throughput),
this._options.maximumConcurrentRequests
);
this._cpuMultiplier = this._options.cpuMultiplier;
this._cpuTaskMultiplier = this._options.cpuTaskMultiplier;
this._layoutTaskMultiplier = this._options.layoutTaskMultiplier;
}

/**
Expand Down Expand Up @@ -250,7 +260,13 @@ class Estimator {
_estimateTimeRemaining(node) {
if (node.type === Node.TYPES.CPU) {
const timingData = this._nodeTiming.get(node);
const totalDuration = Math.round(node.event.dur / 1000 * this._cpuMultiplier);
const multiplier = node.didPerformLayout()
? this._layoutTaskMultiplier
: this._cpuTaskMultiplier;
const totalDuration = Math.min(
Math.round(node.event.dur / 1000 * multiplier),
DEFAULT_MAXIMUM_CPU_TASK_DURATION
);
const estimatedTimeElapsed = totalDuration - timingData.timeElapsed;
this._setTimingData(node, {estimatedTimeElapsed});
return estimatedTimeElapsed;
Expand Down
3 changes: 3 additions & 0 deletions lighthouse-core/gather/computed/page-dependency-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const TracingProcessor = require('../../lib/traces/tracing-processor');

// Tasks smaller than 10 ms have minimal impact on simulation
const MINIMUM_TASK_DURATION_OF_INTEREST = 10;
// video files tend to be enormous and throw off all graph traversals
const IGNORED_MIME_TYPES_REGEX = /^video/;

class PageDependencyGraphArtifact extends ComputedArtifact {
get name() {
Expand Down Expand Up @@ -48,6 +50,7 @@ class PageDependencyGraphArtifact extends ComputedArtifact {
const urlToNodeMap = new Map();

networkRecords.forEach(record => {
if (IGNORED_MIME_TYPES_REGEX.test(record.mimeType)) return;
const node = new NetworkNode(record);
nodes.push(node);

Expand Down
12 changes: 6 additions & 6 deletions lighthouse-core/test/audits/predictive-perf-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ describe('Performance: predictive performance audit', () => {
}, Runner.instantiateComputedArtifacts());

return PredictivePerf.audit(artifacts).then(output => {
assert.equal(output.score, 96);
assert.equal(Math.round(output.rawValue), 2453);
assert.equal(output.displayValue, '2,450\xa0ms');
assert.equal(output.score, 99);
assert.equal(Math.round(output.rawValue), 1696);
assert.equal(output.displayValue, '1,700\xa0ms');

const valueOf = name => Math.round(output.extendedInfo.value[name]);
assert.equal(valueOf('optimisticFMP'), 754);
assert.equal(valueOf('pessimisticFMP'), 2070);
assert.equal(valueOf('optimisticTTCI'), 3340);
assert.equal(valueOf('pessimisticTTCI'), 3649);
assert.equal(valueOf('pessimisticFMP'), 1191);
assert.equal(valueOf('optimisticTTCI'), 2438);
assert.equal(valueOf('pessimisticTTCI'), 2399);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('DependencyGraph/Estimator', () => {
const cpuNode = new CpuNode(cpuTask({duration: 200}));
cpuNode.addDependency(rootNode);

const estimator = new Estimator(rootNode, {fallbackTTFB: 500});
const estimator = new Estimator(rootNode, {fallbackTTFB: 500, cpuTaskMultiplier: 5});
const result = estimator.estimate();
// should be 2 RTTs and 500ms for the server response time + 200 CPU
assert.equal(result, 300 + 500 + 200);
Expand Down Expand Up @@ -83,7 +83,7 @@ describe('DependencyGraph/Estimator', () => {
nodeA.addDependent(nodeC);
nodeA.addDependent(nodeD);

const estimator = new Estimator(nodeA, {fallbackTTFB: 500});
const estimator = new Estimator(nodeA, {fallbackTTFB: 500, cpuTaskMultiplier: 5});
const result = estimator.estimate();
// should be 800ms A, then 1000 ms total for B, C, D in serial
assert.equal(result, 1800);
Expand All @@ -103,7 +103,7 @@ describe('DependencyGraph/Estimator', () => {
nodeC.addDependent(nodeD);
nodeC.addDependent(nodeF); // finishes 400 ms after D

const estimator = new Estimator(nodeA, {fallbackTTFB: 500});
const estimator = new Estimator(nodeA, {fallbackTTFB: 500, cpuTaskMultiplier: 5});
const result = estimator.estimate();
// should be 800ms each for A, B, C, D, with F finishing 400 ms after D
assert.equal(result, 3600);
Expand Down

0 comments on commit 0ff9ef9

Please sign in to comment.