-
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
core: support traces with TracingStartedInBrowser event #5271
Conversation
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.
thanks for the PR!
@@ -45,18 +45,30 @@ class TraceOfTab extends ComputedArtifact { | |||
.filter(e => { | |||
return e.cat.includes('blink.user_timing') || | |||
e.cat.includes('loading') || | |||
e.cat.includes('devtools.timeline') || | |||
e.name === 'TracingStartedInPage'; |
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.
think you don't want to filter this out to support the legacy case? Or in the fallback case need to search for the first TracingStartedInPage
in the original trace.traceEvents
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.
also, does the filter now need to let through e.name === 'TracingStartedInBrowser'
events?
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.
Both TracingStartedInPage and TracingStartedInBrowser are in devtools.timeline category which is already allowed.
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.
It seems like it was in toplevel once upon a time based on the fixture change below?
my traces from ~December have it in disabled-by-default-devtools.timeline
so I guess it's a question of how far back we want to go
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.
AFAICT TracingStartedInPage was introduced 4 years ago with devtools.timeline category. See https://codereview.chromium.org/254613002/diff/90001/Source/core/inspector/InspectorTracingAgent.cpp
I wonder where the traces with it being in toplevel come from?
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.
Hm, no clue then 🤷♂️ 4 years is plenty good enough for me 😆
// Find out the inspected page frame. | ||
let startedInPageEvt; | ||
const startedInBrowserEvt = keyEvents.find(e => e.name === 'TracingStartedInBrowser'); | ||
if (startedInBrowserEvt && startedInBrowserEvt.args.data.persistentIds) { |
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.
what's the significance of persistentIds
? doesn't appear to be used anywhere?
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.
We used to have a TracingStartedInBrowser event before, but with no frames information. persistentIds is a marker that frames are provided.
const startedInBrowserEvt = keyEvents.find(e => e.name === 'TracingStartedInBrowser'); | ||
if (startedInBrowserEvt && startedInBrowserEvt.args.data.persistentIds) { | ||
const mainFrame = (startedInBrowserEvt.args.data.frames || []).find(frame => !frame.parent); | ||
const mainFrameId = mainFrame && mainFrame.frame || ''; |
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.
what's the use of the fallback ''
value here if there's no mainFrame
or mainFrameId
found? Seems like we need those and should just throw if not found
(or could set startedInPageEvt
to undefined
and let the legacy fallback below try to find a backup TracingStartedInPage
event)
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.
Agree
// Beware: the tracingStartedInPage event can appear slightly after a navigationStart | ||
startedInPageEvt = keyEvents.find(e => e.name === 'TracingStartedInPage'); | ||
if (!startedInPageEvt) throw new LHError(LHError.errors.NO_TRACING_STARTED); | ||
// @ts-ignore - property chain exists for 'TracingStartedInPage' event. |
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.
two lines above should be pulled out of the conditional (throw if no startedInPageEvt
found, // @ts-ignore
comment is for the const frameId =
line below)
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.
It doesn't really matter as when we didn't enter the if
block the startedInPageEvt
is already there. Anyway, I will move it.
6840233
to
678d4aa
Compare
@@ -16,6 +16,8 @@ const preactTrace = require('../../fixtures/traces/preactjs.com_ts_of_undefined. | |||
const noFMPtrace = require('../../fixtures/traces/no_fmp_event.json'); | |||
const noFCPtrace = require('../../fixtures/traces/airhorner_no_fcp'); | |||
const backgroundTabTrace = require('../../fixtures/traces/backgrounded-tab-missing-paints'); | |||
const tracingStartedInBrowserTrace = | |||
require('../../fixtures/traces/tracing-started-in-browser.json'); |
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 whole fixture is just to exercise that one event right?
could we use a reduced trace or even just a fake array of events for this? 6k lines for the 1 relevant event is a lot :)
@@ -45,18 +45,30 @@ class TraceOfTab extends ComputedArtifact { | |||
.filter(e => { | |||
return e.cat.includes('blink.user_timing') || | |||
e.cat.includes('loading') || | |||
e.cat.includes('devtools.timeline') || | |||
e.name === 'TracingStartedInPage'; |
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.
It seems like it was in toplevel once upon a time based on the fixture change below?
my traces from ~December have it in disabled-by-default-devtools.timeline
so I guess it's a question of how far back we want to go
@@ -106,12 +121,13 @@ class TraceOfTab extends ComputedArtifact { | |||
// stable-sort events to keep them correctly nested. | |||
/** @type Array<LH.TraceEvent> */ | |||
const processEvents = trace.traceEvents | |||
// @ts-ignore - property chain exists for 'TracingStartedInPage' event. |
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.
hmmm, we shouldn't need the ts-ignore for .pid, what was the error you're suppressing?
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.
error TS2532: Object is possibly 'undefined'.
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.
Oh because startedInPageEvt is LH.TraceEvent|undefined
and we're accessing inside a closure :/
seems like we just need progress on microsoft/TypeScript#11498, mind replacing the ts-ignore explanation with that link or casting instead? /** @type {LH.TraceEvent} */ (startedInPageEvt).pid
(same for .tid below)
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.
Sure, I can annotate. I surprised the compiler hasn't noticed if (!startedInPageEvt) throw
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.
It knows, it's just that there's no mechanism for telling if the callback will be invoked asynchronously or just once synchronously.
const filtered = []
for (const e of events) if (e.pid === startedInPageEvt.pid) filtered.push(e)
works fine
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.
yeah, they still do a lot simpler CFG work than closure, focusing almost entirely locally, so things like this still trip them up even while being more sophisticated in other ways :)
26c4539
to
9f252e3
Compare
// The first TracingStartedInPage in the trace is definitely our renderer thread of interest | ||
// Beware: the tracingStartedInPage event can appear slightly after a navigationStart | ||
startedInPageEvt = keyEvents.find(e => e.name === 'TracingStartedInPage'); | ||
} | ||
if (!startedInPageEvt) throw new LHError(LHError.errors.NO_TRACING_STARTED); | ||
// @ts-ignore - property chain exists for 'TracingStartedInPage' event. | ||
const frameId = startedInPageEvt.args.data.page; |
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 the casts are annoying, could also do something like
/** @type {LH.TraceEvent|undefined} */
let possibleStartedInPageEvt;
...
above, and then here
const startedInPageEvt = possibleStartedInPageEvt;
because the compiler will know that possibleStartedInPageEvt
is definitely defined at this point, the type for startedInPageEvt
will be inferred correctly as LH.TraceEvent
, and then it won't need any casts below this.
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 considered that, but I didn't want to introduce more code to workaround compiler issues. I'm fine with casts.
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.
LGTM! thanks for helping us out here @a1ph! 👍
'args': {'name': 'CrRendererMain'}, | ||
}]}; | ||
const trace = await traceOfTab.compute_(tracingStartedInBrowserTrace); | ||
assert.equal(trace.startedInPageEvt.ts, 2193564729582); |
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.
want to assert the navStart is found and in the trace.mainThreadEvents since I assume that's what the thread_name
addition was for?
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.
Done
Since version 67 Chrome uses a new schema to describe page frame tree. The tree is encoded within TracingStartedInBrowser trace event. The patch makes lighthouse to support the new event. Legacy TracingStartedInPage event is going to the removed soon.
@brendankenny does this look good to go to you? |
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.
just a few style nits, but otherwise LGTM! Thanks for making the change
.filter(e => { | ||
return e.cat.includes('blink.user_timing') || | ||
.filter(e => | ||
e.cat.includes('blink.user_timing') || |
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.
generally for multi-line arrow function we keep the curly braces/return
for clarity. Any reason to drop it 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.
done
let startedInPageEvt; | ||
const startedInBrowserEvt = keyEvents.find(e => e.name === 'TracingStartedInBrowser'); | ||
if (startedInBrowserEvt && startedInBrowserEvt.args.data && | ||
startedInBrowserEvt.args.data.persistentIds) { |
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 about why persistentIds
is significant?
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 talked to dgozman, it was added to ensure this is a new version of the event that carries frames. I think we can just check for frames field being there.
const threadNameEvt = keyEvents.find(e => e.pid === pid && e.ph === 'M' && | ||
e.cat === '__metadata' && e.name === 'thread_name' && | ||
// @ts-ignore - property chain exists for 'thread_name' event. | ||
e.args.name === 'CrRendererMain'); |
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 it's just a single level into args
, add name?: string
to args
in externs.d.ts
instead of @ts-ignore
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.
done
oops you got some conflicts now @a1ph! I had fixed the feedback before you pushed sorry! |
Since version 67 Chrome uses a new schema to describe page frame tree. The tree is encoded within TracingStartedInBrowser trace event. The patch makes lighthouse to support the new event. Legacy TracingStartedInPage event is going to the removed soon.
thanks @a1ph! |
Since version 67 Chrome uses a new schema to describe page frame tree.
The tree is encoded within TracingStartedInBrowser trace event.
The patch makes lighthouse to support the new event.
Legacy TracingStartedInPage event is going to the removed soon.