-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
new_audit: add long-tasks diagnostic audit for surfacing top long tasks #10736
Conversation
@brendankenny @patrickhulce I assume |
Ooh, yeah good catch @connorjclark. It'd be a shame to lose this data. Not only for HA but it's a great diagnostic tool as well. I'm not sure if the visualizations in calibre and such use this or the trace itself. Would you be able to create a |
lighthouse-core/audits/long-tasks.js
Outdated
|
||
const UIStrings = { | ||
/** Title of a diagnostic LH audit that provides details on the longest running tasks that occur when the page loads. */ | ||
title: 'Avoids long-running tasks', |
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.
Since we're just listing the tasks here and not scoring the audit, title should be more declarative than prescriptive: Long main thread tasks
should be fine.
description could be Lists the longest tasks on the main thread, useful for identifying worst contributors to input delay
?
Do we need any sort of web.dev url for this? maybe just link to web.dev/tbt ?
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.
I thought about linking to tbt, but unsure as I don't want this audit to be seen as specifically for tbt.
lighthouse-core/audits/long-tasks.js
Outdated
|
||
const jsURLs = LongTasks.getJavaScriptURLs(networkRecords); | ||
const longtasks = [...tasks].sort((a, b) => b.duration - a.duration) | ||
.filter(t => t.duration >= 50 && t.unbounded === false && !t.parent) |
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.
filter, then sort (less work)
lighthouse-core/audits/long-tasks.js
Outdated
.filter(t => t.duration >= 50 && t.unbounded === false && !t.parent) | ||
.slice(0, 20); | ||
|
||
const results = longtasks.map(t => ({ |
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.
t -> task
lighthouse-core/audits/long-tasks.js
Outdated
* @param {Set<string>} jsURLs | ||
* @return {string} | ||
*/ | ||
static getAttributableURLForTask(task, jsURLs) { |
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.
this is BootupTime.getAttributableURLForTask
right? use that instead?
@@ -1136,12 +1136,6 @@ | |||
"lighthouse-core/audits/timing-budget.js | title": { | |||
"message": "Обмеження часу" | |||
}, | |||
"lighthouse-core/audits/user-timings.js | columnDuration": { |
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.
FYI we will need a string import when this lands @exterkamp
Co-authored-by: Connor Clark <cjamcl@google.com>
can you add a after that I think we're good here |
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.
looks great! nice job @Beytoven!
just a few data inclusion and testing nits but LGTM 🎉
@@ -145,62 +169,35 @@ module.exports = [ | |||
node: { | |||
type: 'node', | |||
nodeLabel: 'img', | |||
path: '2,HTML,1,BODY,0,IMG', | |||
path: '0,HTML,1,BODY,0,DIV,0,IMG', |
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.
maybe we should use \d
to make this less brittle?
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.
I'd prefer removing path
and instead adding something like src
or another unique attribute here (can we match for that in snippet?)
On a quest to reduce paths in smoke tests :) https://github.com/GoogleChrome/lighthouse/pull/10827/files
} | ||
}); | ||
|
||
it('should populate url when tasks have an attributable url', async () => { |
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.
nice touch :)
lighthouse-core/audits/long-tasks.js
Outdated
url: BootupTime.getAttributableURLForTask(task, jsURLs), | ||
group: task.group.label, | ||
start: task.startTime, | ||
self: task.selfTime, |
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.
I'm not sure selfTime is worth including for the toplevel task since anything there is just overhead.
If we include it should we ensure it matches the multiplier too and throw a test on it?
lighthouse-core/audits/long-tasks.js
Outdated
const results = longtasks.map(task => ({ | ||
url: BootupTime.getAttributableURLForTask(task, jsURLs), | ||
group: task.group.label, | ||
start: task.startTime, |
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.
I think it's going to be weird that startTime
is reported on the actual timeline while duration
is going to be on the simulated timeline, should we just exclude it for now?
lighthouse-core/audits/long-tasks.js
Outdated
|
||
const results = longtasks.map(task => ({ | ||
url: BootupTime.getAttributableURLForTask(task, jsURLs), | ||
group: task.group.label, |
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.
don't know if group
is worth including when it's value is always Other
, maybe we exclude it?
Co-authored-by: Patrick Hulce <patrick.hulce@gmail.com>
@@ -84,6 +84,10 @@ const UIStrings = { | |||
columnOverBudget: 'Over Budget', | |||
/** Label for a column in a data table; entries will be a representation of a DOM element. */ | |||
columnElement: 'Element', | |||
/** Label for a column in a data table; entries will be the number of milliseconds since the page started loading. */ | |||
columnStartTime: 'Start Time', |
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.
technically not needed here but I say keep it b/c it will be needed here in your followup
}, | ||
}, | ||
}, | ||
// TODO: uncomment when Chrome m83 lands |
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.
I'm ok with removing this but can you make an issue + assign to yourself so we don't forget to add it back when m84 (comment is wrong) lands?
lhr: { | ||
requestedUrl: 'http://localhost:10200/perf/trace-elements.html', | ||
finalUrl: 'http://localhost:10200/perf/trace-elements.html', | ||
audits: { | ||
'largest-contentful-paint-element': { | ||
score: null, | ||
displayValue: '1 element found', |
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.
driveby: can you remove displayValue
?
devtoolsLogs: {defaultPass: devtoolsLog}, | ||
}; | ||
const result = await LongTasks.audit(artifacts, {computedCache: new Map()}); | ||
// expect(result.score).toBe(0); |
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.
remove
*/ | ||
function generateTraceWithLongTasks( | ||
count, | ||
duration = 200, |
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.
styling nit: we tend to only have line breaks in params if it is too long.
const task = {ts, duration}; | ||
task.children = []; | ||
if (withChildTasks) { | ||
task.children.push({ |
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.
Can you add a comment detailing (or maybe an asci chart) the structure of the child tasks?
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.
Good idea, will do.
const baseTs = 1000; | ||
const traceTasks = []; | ||
for (let i = 1; i <= count; i++) { | ||
const ts = baseTs * i; |
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.
looks like tasks start at 1s instead of 0, is that important?
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.
For this case, yes. I want to avoid any overlapping trace events so that no unintentional parent/child task relationships get formed since we need top level tasks for this audit. So starting at 1s avoids any of the added tasks overlapping with the required tasks defined in CreateTestTrace()
.
}); | ||
|
||
it('should populate url when tasks have an attributable url', async () => { | ||
const trace = generateTraceWithLongTasks(1, 300, true); |
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.
maybe use object parameter? can't tell what these values mean w/o looking at function.
Co-authored-by: Connor Clark <cjamcl@google.com>
Addresses #10705