export function captureObserverEntries()

in packages/rum-core/src/performance-monitoring/metrics/metrics.js [224:307]


export function captureObserverEntries(list, { isHardNavigation, trStart }) {
  const longtaskEntries = list.getEntriesByType(LONG_TASK).filter(entry => {
    return entry.startTime >= trStart
  })
  const longTaskSpans = createLongTaskSpans(longtaskEntries, metrics.longtask)

  const result = {
    spans: longTaskSpans,
    marks: {}
  }
  /**
   * Web vitals including CLS, FID, LCP and other paint metrics are only
   * available for hard navigation
   */
  if (!isHardNavigation) {
    return result
  }
  /**
   * Largest Contentful Paint is a draft spec and its not W3C standard yet
   * Spec - https://wicg.github.io/largest-contentful-paint/
   */
  const lcpEntries = list.getEntriesByType(LARGEST_CONTENTFUL_PAINT)
  /**
   * There can be multiple LCP present on a single page load,
   * We need to always use the last one which takes all the lazy loaded
   * elements in to account
   */
  const lastLcpEntry = lcpEntries[lcpEntries.length - 1]

  if (lastLcpEntry) {
    /**
     * `startTime` -  equals to renderTime if it's nonzero, otherwise equal to loadTime.
     * `renderTime` will not be available for Image element and for the element
     * that is loaded cross-origin without the `Timing-Allow-Origin` header.
     */
    const lcp = parseInt(lastLcpEntry.startTime)
    metrics.lcp = lcp
    result.marks.largestContentfulPaint = lcp
  }

  /**
   * Paint Timing API
   * First Contentful Paint is available only during Page load
   * SPEC - https://www.w3.org/TR/paint-timing/
   */
  const timing = PERF.timing
  /**
   *
   * To avoid capturing the unload event handler effect
   * as part of the page-load transaction duration
   */
  let unloadDiff = timing.fetchStart - timing.navigationStart
  if (isRedirectInfoAvailable(timing)) {
    // this makes sure the FCP startTime includes the redirect time
    // otherwise the mark would not show up properly in the UI waterfall
    unloadDiff = 0
  }

  const fcpEntry = list.getEntriesByName(FIRST_CONTENTFUL_PAINT)[0]
  if (fcpEntry) {
    const fcp = parseInt(
      unloadDiff >= 0 ? fcpEntry.startTime - unloadDiff : fcpEntry.startTime
    )
    metrics.fcp = fcp
    result.marks.firstContentfulPaint = fcp
  }

  /**
   * Capture First Input Delay (FID) as span
   */
  const fidEntries = list.getEntriesByType(FIRST_INPUT)
  const fidSpan = createFirstInputDelaySpan(fidEntries)
  if (fidSpan) {
    metrics.fid = fidSpan.duration()
    result.spans.push(fidSpan)
  }

  calculateTotalBlockingTime(longtaskEntries)

  const clsEntries = list.getEntriesByType(LAYOUT_SHIFT)
  calculateCumulativeLayoutShift(clsEntries)

  return result
}