static getLongAnimationFrameDetails(processedTrace, processedNavigation) {
    const {firstContentfulPaint, timeOrigin} = processedNavigation.timestamps;

    const loafEvents = processedTrace.mainThreadEvents.filter(evt => {
      return evt.name === 'LongAnimationFrame' && evt.ph === 'b';
    });
    if (loafEvents.length === 0) return;

    let currentMaxDuration = -Infinity;
    let currentMaxDurationLoaf;
    let currentMaxBlocking = -Infinity;
    let currentMaxBlockingLoaf;
    const observedLoafs = [];
    for (const loafEvent of loafEvents) {
      const loafDuration = loafEvent.args?.data?.duration;
      const loafBlocking = loafEvent.args?.data?.blockingDuration;
      // Should never happen, so mostly keeping the type checker happy.
      if (loafDuration === undefined || loafBlocking === undefined) continue;

      observedLoafs.push({
        startTime: (loafEvent.ts - timeOrigin) / 1000,
        duration: loafDuration,
        blockingDuration: loafBlocking,
      });

      // Max LoAFs are only considered after FCP.
      if (loafEvent.ts < firstContentfulPaint) continue;

      if (loafDuration > currentMaxDuration) {
        currentMaxDuration = loafDuration;
        currentMaxDurationLoaf = loafEvent;
      }
      if (loafBlocking > currentMaxBlocking) {
        currentMaxBlocking = loafBlocking;
        currentMaxBlockingLoaf = loafEvent;
      }
    }

    return {
      type: 'debugdata',
      observedMaxDurationLoaf: currentMaxDurationLoaf,
      observedMaxBlockingLoaf: currentMaxBlockingLoaf,
      observedLoafs,
    };
  }
Extract potential LoAF replacements for MPFID from the trace to log in
debugdata details.
@param {LH.Artifacts.ProcessedTrace} processedTrace
@param {LH.Artifacts.ProcessedNavigation} processedNavigation
@return {LoafDebugDetails|undefined}