static processNavigation(processedTrace) {
    const {frameEvents, frameTreeEvents, timeOriginEvt, timings, timestamps} = processedTrace;

    // Compute the key frame timings for the main frame.
    const frameTimings = this.computeNavigationTimingsForFrame(frameEvents, {timeOriginEvt});

    // Compute FCP for all frames.
    const fcpAllFramesEvt = frameTreeEvents.find(
      e => e.name === 'firstContentfulPaint' && e.ts > timeOriginEvt.ts
    );

    if (!fcpAllFramesEvt) {
      throw this.createNoFirstContentfulPaintError();
    }

    // Compute LCP for all frames.
    const lcpAllFramesEvt = this.computeValidLCPAllFrames(frameTreeEvents, timeOriginEvt).lcp;

    /** @param {number} ts */
    const getTiming = ts => (ts - timeOriginEvt.ts) / 1000;
    /** @param {number=} ts */
    const maybeGetTiming = (ts) => ts === undefined ? undefined : getTiming(ts);

    return {
      timings: {
        timeOrigin: timings.timeOrigin,
        firstPaint: frameTimings.timings.firstPaint,
        firstContentfulPaint: frameTimings.timings.firstContentfulPaint,
        firstContentfulPaintAllFrames: getTiming(fcpAllFramesEvt.ts),
        largestContentfulPaint: frameTimings.timings.largestContentfulPaint,
        largestContentfulPaintAllFrames: maybeGetTiming(lcpAllFramesEvt?.ts),
        load: frameTimings.timings.load,
        domContentLoaded: frameTimings.timings.domContentLoaded,
        traceEnd: timings.traceEnd,
      },
      timestamps: {
        timeOrigin: timestamps.timeOrigin,
        firstPaint: frameTimings.timestamps.firstPaint,
        firstContentfulPaint: frameTimings.timestamps.firstContentfulPaint,
        firstContentfulPaintAllFrames: fcpAllFramesEvt.ts,
        largestContentfulPaint: frameTimings.timestamps.largestContentfulPaint,
        largestContentfulPaintAllFrames: lcpAllFramesEvt?.ts,
        load: frameTimings.timestamps.load,
        domContentLoaded: frameTimings.timestamps.domContentLoaded,
        traceEnd: timestamps.traceEnd,
      },
      firstPaintEvt: frameTimings.firstPaintEvt,
      firstContentfulPaintEvt: frameTimings.firstContentfulPaintEvt,
      firstContentfulPaintAllFramesEvt: fcpAllFramesEvt,
      largestContentfulPaintEvt: frameTimings.largestContentfulPaintEvt,
      largestContentfulPaintAllFramesEvt: lcpAllFramesEvt,
      loadEvt: frameTimings.loadEvt,
      domContentLoadedEvt: frameTimings.domContentLoadedEvt,
      lcpInvalidated: frameTimings.lcpInvalidated,
    };
  }
Finds key navigation trace events and computes timings of events in milliseconds since the time
origin in addition to the standard microsecond monotonic timestamps.
@param {LH.Artifacts.ProcessedTrace} processedTrace
@return {LH.Artifacts.ProcessedNavigation}