Skip to content

Commit

Permalink
core(bootup-time): refactor task/group iteration
Browse files Browse the repository at this point in the history
  • Loading branch information
paulirish committed Nov 17, 2017
1 parent 05cea61 commit 33b1574
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 52 deletions.
67 changes: 27 additions & 40 deletions lighthouse-core/audits/bootup-time.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,22 +114,25 @@ class BootupTime extends Audit {
*/
static getExecutionTimingsByURL(trace) {
const timelineModel = new DevtoolsTimelineModel(trace);
const bottomUpByName = timelineModel.bottomUpGroupBy('URL');
const bottomUpByURL = timelineModel.bottomUpGroupBy('URL');
const result = new Map();

bottomUpByName.children.forEach((perUrlNode, url) => {
bottomUpByURL.children.forEach((perUrlNode, url) => {
// when url is "" or about:blank, we skip it
if (!url || url === 'about:blank') {
return;
}

const tasks = {};
const taskGroups = {};
perUrlNode.children.forEach((perTaskPerUrlNode) => {
const taskGroup = WebInspector.TimelineUIUtils.eventStyle(perTaskPerUrlNode.event);
tasks[taskGroup.title] = tasks[taskGroup.title] || 0;
tasks[taskGroup.title] += Number((perTaskPerUrlNode.selfTime || 0).toFixed(1));
// eventStyle() returns a string like 'Evaluate Script'
const task = WebInspector.TimelineUIUtils.eventStyle(perTaskPerUrlNode.event);
// Resolve which taskGroup we're using
const groupName = taskToGroup[task.title] || group.other;
const groupTotal = taskGroups[groupName] || 0;
taskGroups[groupName] = groupTotal + (perTaskPerUrlNode.selfTime || 0);
});
result.set(url, tasks);
result.set(url, taskGroups);
});

return result;
Expand All @@ -141,50 +144,34 @@ class BootupTime extends Audit {
*/
static audit(artifacts) {
const trace = artifacts.traces[BootupTime.DEFAULT_PASS];
const bootupTimings = BootupTime.getExecutionTimingsByURL(trace);
const executionTimings = BootupTime.getExecutionTimingsByURL(trace);

let totalBootupTime = 0;
const extendedInfo = {};

const headings = [
{key: 'url', itemType: 'url', text: 'URL'},
{key: 'scripting', itemType: 'text', text: group.scripting},
{key: 'scriptParseCompile', itemType: 'text', text: group.scriptParseCompile},
];

// Group tasks per url
const groupsPerUrl = Array.from(bootupTimings).map(([url, durations]) => {
extendedInfo[url] = durations;

const groups = [];
Object.keys(durations).forEach(task => {
totalBootupTime += durations[task];
const group = taskToGroup[task];

groups[group] = groups[group] || 0;
groups[group] += durations[task];

if (!headings.find(heading => heading.key === group)) {
headings.push(
{key: group, itemType: 'text', text: group}
);
}
});
// map data in correct format to create a table
const results = Array.from(executionTimings).map(([url, groups]) => {
// Add up the totalBootupTime for all the taskGroups
totalBootupTime += Object.keys(groups).reduce((sum, name) => sum += groups[name], 0);
extendedInfo[url] = groups;

const scriptingTotal = groups[group.scripting] || 0;
const parseCompileTotal = groups[group.scriptParseCompile] || 0;
return {
url: url,
groups,
sum: scriptingTotal + parseCompileTotal,
// Only reveal the javascript task costs
// Later we can account for forced layout costs, etc.
scripting: Util.formatMilliseconds(scriptingTotal, 1),
scriptParseCompile: Util.formatMilliseconds(parseCompileTotal, 1),
};
});

// map data in correct format to create a table
const results = groupsPerUrl.map(({url, groups}) => {
const res = {};
headings.forEach(heading => {
res[heading.key] = Util.formatMilliseconds(groups[heading.key] || 0, 1);
});

res.url = url;

return res;
});
}).sort((a, b) => b.sum - a.sum);

const tableDetails = BootupTime.makeTableDetails(headings, results);

Expand Down
28 changes: 16 additions & 12 deletions lighthouse-core/test/audits/bootup-time-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const errorTrace = JSON.parse(
);

describe('Performance: bootup-time audit', () => {
it('should compute the correct BootupTime values', (done) => {
it('should compute the correct BootupTime values', () => {
const artifacts = {
traces: {
[BootupTime.DEFAULT_PASS]: acceptableTrace,
Expand All @@ -33,17 +33,21 @@ describe('Performance: bootup-time audit', () => {
assert.equal(output.score, true);
assert.equal(Math.round(output.rawValue), 176);

const valueOf = name => output.extendedInfo.value[name];
assert.deepEqual(valueOf('https://www.google-analytics.com/analytics.js'), {'Evaluate Script': 40.1, 'Compile Script': 9.6, 'Recalculate Style': 0.2});
assert.deepEqual(valueOf('https://pwa.rocks/script.js'), {'Evaluate Script': 31.8, 'Layout': 5.5, 'Compile Script': 1.3});
assert.deepEqual(valueOf('https://www.googletagmanager.com/gtm.js?id=GTM-Q5SW'), {'Evaluate Script': 25, 'Compile Script': 5.5, 'Recalculate Style': 1.2});
assert.deepEqual(valueOf('https://www.google-analytics.com/plugins/ua/linkid.js'), {'Evaluate Script': 25.2, 'Compile Script': 1.2});
assert.deepEqual(valueOf('https://www.google-analytics.com/cx/api.js?experiment=jdCfRmudTmy-0USnJ8xPbw'), {'Compile Script': 3, 'Evaluate Script': 1.2});
assert.deepEqual(valueOf('https://www.google-analytics.com/cx/api.js?experiment=qvpc5qIfRC2EMnbn6bbN5A'), {'Compile Script': 2.5, 'Evaluate Script': 1});
assert.deepEqual(valueOf('https://pwa.rocks/'), {'Parse HTML': 14.2, 'Evaluate Script': 6.1, 'Compile Script': 1.2});
assert.deepEqual(valueOf('https://pwa.rocks/0ff789bf.js'), {'Parse HTML': 0});

done();
const roundedValueOf = name => {
const value = output.extendedInfo.value[name];
const roundedValue = {};
Object.keys(value).forEach(key => roundedValue[key] = Math.round(value[key] * 10) / 10);
return roundedValue;
};

assert.deepEqual(roundedValueOf('https://www.google-analytics.com/analytics.js'), {'Script Evaluation': 40.1, 'Script Parsing & Compile': 9.6, 'Style & Layout': 0.2});
assert.deepEqual(roundedValueOf('https://pwa.rocks/script.js'), {'Script Evaluation': 31.8, 'Style & Layout': 5.5, 'Script Parsing & Compile': 1.3});
assert.deepEqual(roundedValueOf('https://www.googletagmanager.com/gtm.js?id=GTM-Q5SW'), {'Script Evaluation': 25, 'Script Parsing & Compile': 5.5, 'Style & Layout': 1.2});
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/plugins/ua/linkid.js'), {'Script Evaluation': 25.2, 'Script Parsing & Compile': 1.2});
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/cx/api.js?experiment=jdCfRmudTmy-0USnJ8xPbw'), {'Script Parsing & Compile': 3, 'Script Evaluation': 1.2});
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/cx/api.js?experiment=qvpc5qIfRC2EMnbn6bbN5A'), {'Script Parsing & Compile': 2.5, 'Script Evaluation': 1});
assert.deepEqual(roundedValueOf('https://pwa.rocks/'), {'Parsing DOM': 14.2, 'Script Evaluation': 6.1, 'Script Parsing & Compile': 1.2});
assert.deepEqual(roundedValueOf('https://pwa.rocks/0ff789bf.js'), {'Parsing DOM': 0});
});

it('should get no data when no events are present', () => {
Expand Down

0 comments on commit 33b1574

Please sign in to comment.