Skip to content

Commit 33b1574

Browse files
committed
core(bootup-time): refactor task/group iteration
1 parent 05cea61 commit 33b1574

File tree

2 files changed

+43
-52
lines changed

2 files changed

+43
-52
lines changed

lighthouse-core/audits/bootup-time.js

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -114,22 +114,25 @@ class BootupTime extends Audit {
114114
*/
115115
static getExecutionTimingsByURL(trace) {
116116
const timelineModel = new DevtoolsTimelineModel(trace);
117-
const bottomUpByName = timelineModel.bottomUpGroupBy('URL');
117+
const bottomUpByURL = timelineModel.bottomUpGroupBy('URL');
118118
const result = new Map();
119119

120-
bottomUpByName.children.forEach((perUrlNode, url) => {
120+
bottomUpByURL.children.forEach((perUrlNode, url) => {
121121
// when url is "" or about:blank, we skip it
122122
if (!url || url === 'about:blank') {
123123
return;
124124
}
125125

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

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

146149
let totalBootupTime = 0;
147150
const extendedInfo = {};
151+
148152
const headings = [
149153
{key: 'url', itemType: 'url', text: 'URL'},
154+
{key: 'scripting', itemType: 'text', text: group.scripting},
155+
{key: 'scriptParseCompile', itemType: 'text', text: group.scriptParseCompile},
150156
];
151157

152-
// Group tasks per url
153-
const groupsPerUrl = Array.from(bootupTimings).map(([url, durations]) => {
154-
extendedInfo[url] = durations;
155-
156-
const groups = [];
157-
Object.keys(durations).forEach(task => {
158-
totalBootupTime += durations[task];
159-
const group = taskToGroup[task];
160-
161-
groups[group] = groups[group] || 0;
162-
groups[group] += durations[task];
163-
164-
if (!headings.find(heading => heading.key === group)) {
165-
headings.push(
166-
{key: group, itemType: 'text', text: group}
167-
);
168-
}
169-
});
158+
// map data in correct format to create a table
159+
const results = Array.from(executionTimings).map(([url, groups]) => {
160+
// Add up the totalBootupTime for all the taskGroups
161+
totalBootupTime += Object.keys(groups).reduce((sum, name) => sum += groups[name], 0);
162+
extendedInfo[url] = groups;
170163

164+
const scriptingTotal = groups[group.scripting] || 0;
165+
const parseCompileTotal = groups[group.scriptParseCompile] || 0;
171166
return {
172167
url: url,
173-
groups,
168+
sum: scriptingTotal + parseCompileTotal,
169+
// Only reveal the javascript task costs
170+
// Later we can account for forced layout costs, etc.
171+
scripting: Util.formatMilliseconds(scriptingTotal, 1),
172+
scriptParseCompile: Util.formatMilliseconds(parseCompileTotal, 1),
174173
};
175-
});
176-
177-
// map data in correct format to create a table
178-
const results = groupsPerUrl.map(({url, groups}) => {
179-
const res = {};
180-
headings.forEach(heading => {
181-
res[heading.key] = Util.formatMilliseconds(groups[heading.key] || 0, 1);
182-
});
183-
184-
res.url = url;
185-
186-
return res;
187-
});
174+
}).sort((a, b) => b.sum - a.sum);
188175

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

lighthouse-core/test/audits/bootup-time-test.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const errorTrace = JSON.parse(
2121
);
2222

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

36-
const valueOf = name => output.extendedInfo.value[name];
37-
assert.deepEqual(valueOf('https://www.google-analytics.com/analytics.js'), {'Evaluate Script': 40.1, 'Compile Script': 9.6, 'Recalculate Style': 0.2});
38-
assert.deepEqual(valueOf('https://pwa.rocks/script.js'), {'Evaluate Script': 31.8, 'Layout': 5.5, 'Compile Script': 1.3});
39-
assert.deepEqual(valueOf('https://www.googletagmanager.com/gtm.js?id=GTM-Q5SW'), {'Evaluate Script': 25, 'Compile Script': 5.5, 'Recalculate Style': 1.2});
40-
assert.deepEqual(valueOf('https://www.google-analytics.com/plugins/ua/linkid.js'), {'Evaluate Script': 25.2, 'Compile Script': 1.2});
41-
assert.deepEqual(valueOf('https://www.google-analytics.com/cx/api.js?experiment=jdCfRmudTmy-0USnJ8xPbw'), {'Compile Script': 3, 'Evaluate Script': 1.2});
42-
assert.deepEqual(valueOf('https://www.google-analytics.com/cx/api.js?experiment=qvpc5qIfRC2EMnbn6bbN5A'), {'Compile Script': 2.5, 'Evaluate Script': 1});
43-
assert.deepEqual(valueOf('https://pwa.rocks/'), {'Parse HTML': 14.2, 'Evaluate Script': 6.1, 'Compile Script': 1.2});
44-
assert.deepEqual(valueOf('https://pwa.rocks/0ff789bf.js'), {'Parse HTML': 0});
45-
46-
done();
36+
const roundedValueOf = name => {
37+
const value = output.extendedInfo.value[name];
38+
const roundedValue = {};
39+
Object.keys(value).forEach(key => roundedValue[key] = Math.round(value[key] * 10) / 10);
40+
return roundedValue;
41+
};
42+
43+
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/analytics.js'), {'Script Evaluation': 40.1, 'Script Parsing & Compile': 9.6, 'Style & Layout': 0.2});
44+
assert.deepEqual(roundedValueOf('https://pwa.rocks/script.js'), {'Script Evaluation': 31.8, 'Style & Layout': 5.5, 'Script Parsing & Compile': 1.3});
45+
assert.deepEqual(roundedValueOf('https://www.googletagmanager.com/gtm.js?id=GTM-Q5SW'), {'Script Evaluation': 25, 'Script Parsing & Compile': 5.5, 'Style & Layout': 1.2});
46+
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/plugins/ua/linkid.js'), {'Script Evaluation': 25.2, 'Script Parsing & Compile': 1.2});
47+
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/cx/api.js?experiment=jdCfRmudTmy-0USnJ8xPbw'), {'Script Parsing & Compile': 3, 'Script Evaluation': 1.2});
48+
assert.deepEqual(roundedValueOf('https://www.google-analytics.com/cx/api.js?experiment=qvpc5qIfRC2EMnbn6bbN5A'), {'Script Parsing & Compile': 2.5, 'Script Evaluation': 1});
49+
assert.deepEqual(roundedValueOf('https://pwa.rocks/'), {'Parsing DOM': 14.2, 'Script Evaluation': 6.1, 'Script Parsing & Compile': 1.2});
50+
assert.deepEqual(roundedValueOf('https://pwa.rocks/0ff789bf.js'), {'Parsing DOM': 0});
4751
});
4852

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

0 commit comments

Comments
 (0)