-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
core: remove dependency on DevtoolsTimelineModel #5533
Changes from 6 commits
e2162f5
b15c188
279e49d
155b3ad
657f7de
cec72cd
99ab3e1
6dd725e
d2def08
d712444
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,8 @@ | |
'use strict'; | ||
|
||
const Audit = require('./audit'); | ||
const WebInspector = require('../lib/web-inspector'); | ||
const Util = require('../report/html/renderer/util'); | ||
const {groupIdToName, taskToGroup} = require('../lib/task-groups'); | ||
const {taskGroups} = require('../lib/task-groups'); | ||
|
||
class BootupTime extends Audit { | ||
/** | ||
|
@@ -41,33 +40,22 @@ class BootupTime extends Audit { | |
} | ||
|
||
/** | ||
* Returns a mapping of URL to counts of event groups. | ||
* @param {LH.Artifacts.DevtoolsTimelineModel} timelineModel | ||
* @return {Map<string, Object<string, number>>} | ||
* @param {LH.Artifacts.TaskNode[]} tasks | ||
* @param {number} multiplier | ||
* @return {Map<string, Object<keyof taskGroups, number>>} | ||
*/ | ||
static getExecutionTimingsByURL(timelineModel) { | ||
const bottomUpByURL = timelineModel.bottomUpGroupBy('URL'); | ||
static getExecutionTimingsByURL(tasks, multiplier) { | ||
/** @type {Map<string, Object<string, number>>} */ | ||
const result = new Map(); | ||
|
||
bottomUpByURL.children.forEach((perUrlNode, url) => { | ||
// when url is "" or about:blank, we skip it | ||
if (!url || url === 'about:blank') { | ||
return; | ||
} | ||
|
||
/** @type {Object<string, number>} */ | ||
const taskGroups = {}; | ||
perUrlNode.children.forEach((perTaskPerUrlNode) => { | ||
// 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] || groupIdToName.other; | ||
const groupTotal = taskGroups[groupName] || 0; | ||
taskGroups[groupName] = groupTotal + (perTaskPerUrlNode.selfTime || 0); | ||
}); | ||
result.set(url, taskGroups); | ||
}); | ||
for (const task of tasks) { | ||
if (!task.attributableURL || task.attributableURL === 'about:blank') continue; | ||
|
||
const timingByGroupId = result.get(task.attributableURL) || {}; | ||
const originalTime = timingByGroupId[task.group.id] || 0; | ||
timingByGroupId[task.group.id] = originalTime + task.selfTime * multiplier; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. feels weird to apply the multiplier in here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh funny I moved it there because it natural in the computation of time instead of a post-step :) I don't feel that strongly though, done. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ha, it reads better inlined to me too |
||
result.set(task.attributableURL, timingByGroupId); | ||
} | ||
|
||
return result; | ||
} | ||
|
@@ -80,47 +68,47 @@ class BootupTime extends Audit { | |
static async audit(artifacts, context) { | ||
const settings = context.settings || {}; | ||
const trace = artifacts.traces[BootupTime.DEFAULT_PASS]; | ||
const devtoolsTimelineModel = await artifacts.requestDevtoolsTimelineModel(trace); | ||
const executionTimings = BootupTime.getExecutionTimingsByURL(devtoolsTimelineModel); | ||
let totalBootupTime = 0; | ||
/** @type {Object<string, Object<string, number>>} */ | ||
const extendedInfo = {}; | ||
|
||
const headings = [ | ||
{key: 'url', itemType: 'url', text: 'URL'}, | ||
{key: 'scripting', granularity: 1, itemType: 'ms', text: groupIdToName.scripting}, | ||
{key: 'scriptParseCompile', granularity: 1, itemType: 'ms', | ||
text: groupIdToName.scriptParseCompile}, | ||
]; | ||
|
||
const tasks = await artifacts.requestMainThreadTasks(trace); | ||
const multiplier = settings.throttlingMethod === 'simulate' ? | ||
settings.throttling.cpuSlowdownMultiplier : 1; | ||
// map data in correct format to create a table | ||
|
||
const executionTimings = BootupTime.getExecutionTimingsByURL(tasks, multiplier); | ||
|
||
let totalBootupTime = 0; | ||
const results = Array.from(executionTimings) | ||
.map(([url, groups]) => { | ||
.map(([url, timingByGroupId]) => { | ||
// Add up the totalBootupTime for all the taskGroups | ||
for (const [name, value] of Object.entries(groups)) { | ||
groups[name] = value * multiplier; | ||
totalBootupTime += value * multiplier; | ||
let bootupTimeForURL = 0; | ||
for (const timespanMs of Object.values(timingByGroupId)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reduce? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not since we're moving the multiplier down, otherwise yes :) |
||
bootupTimeForURL += timespanMs; | ||
} | ||
|
||
extendedInfo[url] = groups; | ||
totalBootupTime += bootupTimeForURL; | ||
|
||
const scriptingTotal = timingByGroupId[taskGroups.scriptEvaluation.id] || 0; | ||
const parseCompileTotal = timingByGroupId[taskGroups.scriptParseCompile.id] || 0; | ||
|
||
const scriptingTotal = groups[groupIdToName.scripting] || 0; | ||
const parseCompileTotal = groups[groupIdToName.scriptParseCompile] || 0; | ||
return { | ||
url: url, | ||
sum: scriptingTotal + parseCompileTotal, | ||
// Only reveal the javascript task costs | ||
// Later we can account for forced layout costs, etc. | ||
total: bootupTimeForURL, | ||
// Highlight the JavaScript task costs | ||
scripting: scriptingTotal, | ||
scriptParseCompile: parseCompileTotal, | ||
}; | ||
}) | ||
.filter(result => result.sum >= context.options.thresholdInMs) | ||
.sort((a, b) => b.sum - a.sum); | ||
.filter(result => result.total >= context.options.thresholdInMs) | ||
.sort((a, b) => b.total - a.total); | ||
|
||
const summary = {wastedMs: totalBootupTime}; | ||
|
||
const headings = [ | ||
{key: 'url', itemType: 'url', text: 'URL'}, | ||
{key: 'total', granularity: 1, itemType: 'ms', text: 'Total'}, | ||
{key: 'scripting', granularity: 1, itemType: 'ms', text: taskGroups.scriptEvaluation.label}, | ||
{key: 'scriptParseCompile', granularity: 1, itemType: 'ms', | ||
text: taskGroups.scriptParseCompile.label}, | ||
]; | ||
|
||
const details = BootupTime.makeTableDetails(headings, results, summary); | ||
|
||
const score = Audit.computeLogNormalScore( | ||
|
@@ -134,9 +122,6 @@ class BootupTime extends Audit { | |
rawValue: totalBootupTime, | ||
displayValue: [Util.MS_DISPLAY_VALUE, totalBootupTime], | ||
details, | ||
extendedInfo: { | ||
value: extendedInfo, | ||
}, | ||
}; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,7 @@ | |
|
||
const Audit = require('./audit'); | ||
const Util = require('../report/html/renderer/util'); | ||
// We group all trace events into groups to show a highlevel breakdown of the page | ||
const {taskToGroup} = require('../lib/task-groups'); | ||
const {taskGroups} = require('../lib/task-groups'); | ||
|
||
class MainThreadWorkBreakdown extends Audit { | ||
/** | ||
|
@@ -43,15 +42,18 @@ class MainThreadWorkBreakdown extends Audit { | |
} | ||
|
||
/** | ||
* @param {LH.Artifacts.DevtoolsTimelineModel} timelineModel | ||
* @param {LH.Artifacts.TaskNode[]} tasks | ||
* @param {number} multiplier | ||
* @return {Map<string, number>} | ||
*/ | ||
static getExecutionTimingsByCategory(timelineModel) { | ||
const bottomUpByName = timelineModel.bottomUpGroupBy('EventName'); | ||
|
||
static getExecutionTimingsByGroup(tasks, multiplier) { | ||
/** @type {Map<string, number>} */ | ||
const result = new Map(); | ||
bottomUpByName.children.forEach((event, eventName) => | ||
result.set(eventName, event.selfTime)); | ||
|
||
for (const task of tasks) { | ||
const originalTime = result.get(task.group.id) || 0; | ||
result.set(task.group.id, originalTime + task.selfTime * multiplier); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment about the inlined multiplier. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
} | ||
|
||
return result; | ||
} | ||
|
@@ -65,40 +67,33 @@ class MainThreadWorkBreakdown extends Audit { | |
const settings = context.settings || {}; | ||
const trace = artifacts.traces[MainThreadWorkBreakdown.DEFAULT_PASS]; | ||
|
||
const devtoolsTimelineModel = await artifacts.requestDevtoolsTimelineModel(trace); | ||
const executionTimings = MainThreadWorkBreakdown.getExecutionTimingsByCategory( | ||
devtoolsTimelineModel | ||
); | ||
let totalExecutionTime = 0; | ||
|
||
const tasks = await artifacts.requestMainThreadTasks(trace); | ||
const multiplier = settings.throttlingMethod === 'simulate' ? | ||
settings.throttling.cpuSlowdownMultiplier : 1; | ||
|
||
const extendedInfo = {}; | ||
const executionTimings = MainThreadWorkBreakdown.getExecutionTimingsByGroup(tasks, multiplier); | ||
|
||
let totalExecutionTime = 0; | ||
const categoryTotals = {}; | ||
const results = Array.from(executionTimings).map(([eventName, duration]) => { | ||
duration *= multiplier; | ||
const results = Array.from(executionTimings).map(([groupId, duration]) => { | ||
totalExecutionTime += duration; | ||
extendedInfo[eventName] = duration; | ||
const groupName = taskToGroup[eventName]; | ||
|
||
const categoryTotal = categoryTotals[groupName] || 0; | ||
categoryTotals[groupName] = categoryTotal + duration; | ||
const categoryTotal = categoryTotals[groupId] || 0; | ||
categoryTotals[groupId] = categoryTotal + duration; | ||
|
||
return { | ||
category: eventName, | ||
group: groupName, | ||
group: groupId, | ||
groupLabel: taskGroups[groupId].label, | ||
duration: duration, | ||
}; | ||
}); | ||
|
||
const headings = [ | ||
{key: 'group', itemType: 'text', text: 'Category'}, | ||
{key: 'category', itemType: 'text', text: 'Work'}, | ||
{key: 'duration', itemType: 'ms', granularity: 1, text: 'Time spent'}, | ||
{key: 'groupLabel', itemType: 'text', text: 'Category'}, | ||
{key: 'duration', itemType: 'ms', granularity: 1, text: 'Time Spent'}, | ||
]; | ||
// @ts-ignore - stableSort added to Array by WebInspector | ||
results.stableSort((a, b) => categoryTotals[b.group] - categoryTotals[a.group]); | ||
|
||
results.sort((a, b) => categoryTotals[b.group] - categoryTotals[a.group]); | ||
const tableDetails = MainThreadWorkBreakdown.makeTableDetails(headings, results); | ||
|
||
const score = Audit.computeLogNormalScore( | ||
|
@@ -112,9 +107,6 @@ class MainThreadWorkBreakdown extends Audit { | |
rawValue: totalExecutionTime, | ||
displayValue: [Util.MS_DISPLAY_VALUE, totalExecutionTime], | ||
details: tableDetails, | ||
extendedInfo: { | ||
value: extendedInfo, | ||
}, | ||
}; | ||
} | ||
} | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you use
keyof
in theObject<>
type (or anything reasonably complicated, it seems), tsc gets confused and promotes toany
, so should useRecord<>
here (maybe we should just give up onObject
and always useRecord
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
had to widen it to
string
anyhow