{"version":3,"file":"reactComponentTracker.mjs","names":["React"],"sources":["../../../src/domain/performance/reactComponentTracker.tsx"],"sourcesContent":["import * as React from 'react'\nimport { createTimer } from './timer'\nimport { addDurationVital } from './addDurationVital'\n\n/**\n * Track the performance of a React component.\n *\n * @experimental\n */\n// eslint-disable-next-line\nexport const UNSTABLE_ReactComponentTracker = ({\n  name: componentName,\n  children,\n}: {\n  name: string\n  children?: React.ReactNode\n}) => {\n  const isFirstRender = React.useRef(true)\n\n  const renderTimer = createTimer()\n  const effectTimer = createTimer()\n  const layoutEffectTimer = createTimer()\n\n  const onEffectEnd = () => {\n    const renderDuration = renderTimer.getDuration() ?? 0\n    const effectDuration = effectTimer.getDuration() ?? 0\n    const layoutEffectDuration = layoutEffectTimer.getDuration() ?? 0\n\n    const totalRenderTime = renderDuration + effectDuration + layoutEffectDuration\n\n    addDurationVital('reactComponentRender', {\n      description: componentName,\n      startTime: renderTimer.getStartTime()!, // note: renderTimer should have been started at this point, so getStartTime should not return undefined\n      duration: totalRenderTime,\n      context: {\n        is_first_render: isFirstRender.current,\n        render_phase_duration: renderDuration,\n        effect_phase_duration: effectDuration,\n        layout_effect_phase_duration: layoutEffectDuration,\n        framework: 'react',\n      },\n    })\n\n    isFirstRender.current = false\n  }\n\n  // In react, children are rendered sequentially in the order they are defined. that's why we can\n  // measure perf timings of a component by starting recordings in the component above and stopping\n  // them in the component below.\n  return (\n    <>\n      <LifeCycle\n        onRender={renderTimer.startTimer}\n        onLayoutEffect={layoutEffectTimer.startTimer}\n        onEffect={effectTimer.startTimer}\n      />\n      {children}\n      <LifeCycle\n        onRender={renderTimer.stopTimer}\n        onLayoutEffect={layoutEffectTimer.stopTimer}\n        onEffect={() => {\n          effectTimer.stopTimer()\n          onEffectEnd()\n        }}\n      />\n    </>\n  )\n}\n\nfunction LifeCycle({\n  onRender,\n  onLayoutEffect,\n  onEffect,\n}: {\n  onRender: () => void\n  onLayoutEffect: () => void\n  onEffect: () => void\n}) {\n  onRender()\n  React.useLayoutEffect(onLayoutEffect)\n  React.useEffect(onEffect)\n  return null\n}\n"],"mappings":";;;;;;;;;AAUA,MAAa,kCAAkC,EAC7C,MAAM,eACN,eAII;CACJ,MAAM,gBAAgBA,QAAM,OAAO,IAAI;CAEvC,MAAM,cAAc,YAAY;CAChC,MAAM,cAAc,YAAY;CAChC,MAAM,oBAAoB,YAAY;CAEtC,MAAM,oBAAoB;EACxB,MAAM,iBAAiB,YAAY,YAAY,KAAK;EACpD,MAAM,iBAAiB,YAAY,YAAY,KAAK;EACpD,MAAM,uBAAuB,kBAAkB,YAAY,KAAK;EAEhE,MAAM,kBAAkB,iBAAiB,iBAAiB;EAE1D,iBAAiB,wBAAwB;GACvC,aAAa;GACb,WAAW,YAAY,aAAa;GACpC,UAAU;GACV,SAAS;IACP,iBAAiB,cAAc;IAC/B,uBAAuB;IACvB,uBAAuB;IACvB,8BAA8B;IAC9B,WAAW;GACb;EACF,CAAC;EAED,cAAc,UAAU;CAC1B;CAKA,OACE,wBAAA,cAAA,QAAA,UAAA,MACE,wBAAA,cAAC,WAAD;EACE,UAAU,YAAY;EACtB,gBAAgB,kBAAkB;EAClC,UAAU,YAAY;CACvB,CAAA,GACA,UACD,wBAAA,cAAC,WAAD;EACE,UAAU,YAAY;EACtB,gBAAgB,kBAAkB;EAClC,gBAAgB;GACd,YAAY,UAAU;GACtB,YAAY;EACd;CACD,CAAA,CACD;AAEN;AAEA,SAAS,UAAU,EACjB,UACA,gBACA,YAKC;CACD,SAAS;CACT,QAAM,gBAAgB,cAAc;CACpC,QAAM,UAAU,QAAQ;CACxB,OAAO;AACT"}