Skip to content

Commit

Permalink
core(driver): enable async stacks (#5504)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce authored and paulirish committed Apr 18, 2019
1 parent ecd10ef commit b11d3d6
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 7 deletions.
20 changes: 17 additions & 3 deletions lighthouse-core/computed/page-dependency-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,23 @@ class PageDependencyGraph {
static getNetworkInitiators(record) {
if (!record.initiator) return [];
if (record.initiator.url) return [record.initiator.url];
if (record.initiator.type === 'script' && record.initiator.stack) {
const frames = record.initiator.stack.callFrames;
return Array.from(new Set(frames.map(frame => frame.url))).filter(Boolean);
if (record.initiator.type === 'script') {
// Script initiators have the stack of callFrames from all functions that led to this request.
// If async stacks are enabled, then the stack will also have the parent functions that asynchronously
// led to this request chained in the `parent` property.
/** @type {Set<string>} */
const scriptURLs = new Set();
let stack = record.initiator.stack;
while (stack) {
const callFrames = stack.callFrames || [];
for (const frame of callFrames) {
if (frame.url) scriptURLs.add(frame.url);
}

stack = stack.parent;
}

return Array.from(scriptURLs);
}

return [];
Expand Down
15 changes: 12 additions & 3 deletions lighthouse-core/gather/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -1337,9 +1337,6 @@ class Driver {
const uniqueCategories = Array.from(new Set(traceCategories));

// Check any domains that could interfere with or add overhead to the trace.
if (this.isDomainEnabled('Debugger')) {
throw new Error('Debugger domain enabled when starting trace');
}
if (this.isDomainEnabled('CSS')) {
throw new Error('CSS domain enabled when starting trace');
}
Expand Down Expand Up @@ -1405,6 +1402,18 @@ class Driver {
return this.sendCommand('Runtime.enable');
}

/**
* Enables `Debugger` domain to receive async stacktrace information on network request initiators.
* This is critical for tracing certain performance simulation situations.
*
* @return {Promise<void>}
*/
async enableAsyncStacks() {
await this.sendCommand('Debugger.enable');
await this.sendCommand('Debugger.setSkipAllPauses', {skip: true});
await this.sendCommand('Debugger.setAsyncCallStackDepth', {maxDepth: 8});
}

/**
* @param {LH.Config.Settings} settings
* @return {Promise<void>}
Expand Down
3 changes: 2 additions & 1 deletion lighthouse-core/gather/gather-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const Driver = require('../gather/driver.js'); // eslint-disable-line no-unused-
* i. assertNoSameOriginServiceWorkerClients
* ii. retrieve and save userAgent
* iii. beginEmulation
* iv. enableRuntimeEvents
* iv. enableRuntimeEvents/enableAsyncStacks
* v. evaluateScriptOnLoad rescue native Promise from potential polyfill
* vi. register a performance observer
* vii. register dialog dismisser
Expand Down Expand Up @@ -109,6 +109,7 @@ class GatherRunner {
await driver.assertNoSameOriginServiceWorkerClients(options.requestedUrl);
await driver.beginEmulation(options.settings);
await driver.enableRuntimeEvents();
await driver.enableAsyncStacks();
await driver.cacheNatives();
await driver.registerPerformanceObserver();
await driver.dismissJavaScriptDialogs();
Expand Down
25 changes: 25 additions & 0 deletions lighthouse-core/test/computed/page-dependency-graph-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,31 @@ describe('PageDependencyGraph computed artifact:', () => {
assert.equal(nodes[2].isMainDocument(), false);
});

it('should link up script initiators', () => {
const request1 = createRequest(1, '1', 0);
const request2 = createRequest(2, '2', 5);
const request3 = createRequest(3, '3', 5);
const request4 = createRequest(4, '4', 20);
request4.initiator = {
type: 'script',
stack: {callFrames: [{url: '2'}], parent: {parent: {callFrames: [{url: '3'}]}}},
};
const networkRecords = [request1, request2, request3, request4];

addTaskEvents(0, 0, []);

const graph = PageDependencyGraph.createGraph(traceOfTab, networkRecords);
const nodes = [];
graph.traverse(node => nodes.push(node));

assert.equal(nodes.length, 4);
assert.deepEqual(nodes.map(node => node.id), [1, 2, 3, 4]);
assert.deepEqual(nodes[0].getDependencies(), []);
assert.deepEqual(nodes[1].getDependencies(), [nodes[0]]);
assert.deepEqual(nodes[2].getDependencies(), [nodes[0]]);
assert.deepEqual(nodes[3].getDependencies(), [nodes[1], nodes[2]]);
});

it('should throw when root node is not related to main document', () => {
const request1 = createRequest(1, '1', 0, null, NetworkRequest.TYPES.Other);
const request2 = createRequest(2, '2', 5, null, NetworkRequest.TYPES.Document);
Expand Down
3 changes: 3 additions & 0 deletions lighthouse-core/test/gather/fake-driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ function makeFakeDriver({protocolGetVersionResponse}) {
enableRuntimeEvents() {
return Promise.resolve();
},
enableAsyncStacks() {
return Promise.resolve();
},
evaluateScriptOnLoad() {
return Promise.resolve();
},
Expand Down
5 changes: 5 additions & 0 deletions lighthouse-core/test/gather/gather-runner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ function getMockedEmulationDriver(emulationFn, netThrottleFn, cpuThrottleFn,
enableRuntimeEvents() {
return Promise.resolve();
}
enableAsyncStacks() {
return Promise.resolve();
}
assertNoSameOriginServiceWorkerClients() {
return Promise.resolve();
}
Expand Down Expand Up @@ -333,6 +336,7 @@ describe('GatherRunner', function() {
setThrottling: asyncFunc,
dismissJavaScriptDialogs: asyncFunc,
enableRuntimeEvents: asyncFunc,
enableAsyncStacks: asyncFunc,
cacheNatives: asyncFunc,
gotoURL: asyncFunc,
registerPerformanceObserver: asyncFunc,
Expand Down Expand Up @@ -392,6 +396,7 @@ describe('GatherRunner', function() {
setThrottling: asyncFunc,
dismissJavaScriptDialogs: asyncFunc,
enableRuntimeEvents: asyncFunc,
enableAsyncStacks: asyncFunc,
cacheNatives: asyncFunc,
gotoURL: asyncFunc,
registerPerformanceObserver: asyncFunc,
Expand Down

0 comments on commit b11d3d6

Please sign in to comment.