in src/sdk/lh-trace-processor.ts [456:549]
static findMainFrameIds(events) {
// Prefer the newer TracingStartedInBrowser event first, if it exists
const startedInBrowserEvt = events.find(
e => e.name === 'TracingStartedInBrowser'
);
if (
startedInBrowserEvt &&
startedInBrowserEvt.args.data &&
startedInBrowserEvt.args.data.frames
) {
const mainFrame = startedInBrowserEvt.args.data.frames.find(
frame => !frame.parent
);
const frameId = mainFrame && mainFrame.frame;
const pid = mainFrame && mainFrame.processId;
const threadNameEvt = events.find(
e =>
e.pid === pid &&
e.ph === 'M' &&
e.cat === '__metadata' &&
e.name === 'thread_name' &&
e.args.name === 'CrRendererMain'
);
const tid = threadNameEvt && threadNameEvt.tid;
if (pid && tid && frameId) {
return {
pid,
tid,
frameId,
};
}
}
// Support legacy browser versions that do not emit TracingStartedInBrowser event.
// The first TracingStartedInPage in the trace is definitely our renderer thread of interest
// Beware: the tracingStartedInPage event can appear slightly after a navigationStart
const startedInPageEvt = events.find(
e => e.name === 'TracingStartedInPage'
);
if (
startedInPageEvt &&
startedInPageEvt.args &&
startedInPageEvt.args.data
) {
const frameId = startedInPageEvt.args.data.page;
if (frameId) {
return {
pid: startedInPageEvt.pid,
tid: startedInPageEvt.tid,
frameId,
};
}
}
// Support the case where everything else fails, see https://github.com/GoogleChrome/lighthouse/issues/7118.
// If we can't find either TracingStarted event, then we'll fallback to the first navStart that
// looks like it was loading the main frame with a real URL. Because the schema for this event
// has changed across Chrome versions, we'll be extra defensive about finding this case.
const navStartEvt = events.find(e =>
Boolean(
e.name === 'navigationStart' &&
e.args &&
e.args.data &&
e.args.data.isLoadingMainFrame &&
e.args.data.documentLoaderURL
)
);
// Find the first resource that was requested and make sure it agrees on the id.
const firstResourceSendEvt = events.find(
e => e.name === 'ResourceSendRequest'
);
// We know that these properties exist if we found the events, but TSC doesn't.
if (
navStartEvt &&
navStartEvt.args &&
navStartEvt.args.data &&
firstResourceSendEvt &&
firstResourceSendEvt.pid === navStartEvt.pid &&
firstResourceSendEvt.tid === navStartEvt.tid
) {
const frameId = navStartEvt.args.frame;
if (frameId) {
return {
pid: navStartEvt.pid,
tid: navStartEvt.tid,
frameId,
};
}
}
throw this.createNoTracingStartedError();
}