next.js/packages/next/src/server/client-component-renderer-logger.ts
client-component-renderer-logger.ts67 lines1.7 KB
import type { AppPageModule } from './route-modules/app-page/module'

// Combined load times for loading client components
let clientComponentLoadStart = 0
let clientComponentLoadTimes = 0
let clientComponentLoadCount = 0

export function wrapClientComponentLoader(
  ComponentMod: AppPageModule,
  isTracingEnabled: boolean
): AppPageModule['__next_app__'] {
  if (
    !('performance' in globalThis) ||
    (!process.env.NEXT_OTEL_PERFORMANCE_PREFIX && !isTracingEnabled)
  ) {
    return ComponentMod.__next_app__
  }

  return {
    require: (...args) => {
      const startTime = performance.now()

      if (clientComponentLoadStart === 0) {
        clientComponentLoadStart = startTime
      }

      try {
        clientComponentLoadCount += 1
        return ComponentMod.__next_app__.require(...args)
      } finally {
        clientComponentLoadTimes += performance.now() - startTime
      }
    },
    loadChunk: (...args) => {
      const startTime = performance.now()
      const result = ComponentMod.__next_app__.loadChunk(...args)
      // Avoid wrapping `loadChunk`'s result in an extra promise in case something like React depends on its identity.
      // We only need to know when it's settled.
      result.finally(() => {
        clientComponentLoadTimes += performance.now() - startTime
      })
      return result
    },
  }
}

export function getClientComponentLoaderMetrics(
  options: { reset?: boolean } = {}
) {
  const metrics =
    clientComponentLoadStart === 0
      ? undefined
      : {
          clientComponentLoadStart,
          clientComponentLoadTimes,
          clientComponentLoadCount,
        }

  if (options.reset) {
    clientComponentLoadStart = 0
    clientComponentLoadTimes = 0
    clientComponentLoadCount = 0
  }

  return metrics
}
Quest for Codev2.0.0
/
SIGN IN