static findMainFrameIds()

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();
  }