UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

85 lines (82 loc) 2.83 kB
import React, { useCallback, memo, useRef } from 'react'; import { isSSR } from '../core-utils/is-ssr'; import { RenderMarker } from './RenderMarker'; /** * Props for SSRRenderMeasure component */ function SSRRenderMeasureImpl({ onSSRMeasure, segmentName, startTimestampRef, children }) { const wasMeasured = useRef(false); const handleOnRender = useCallback(() => { if (wasMeasured.current) { return; } onSSRMeasure === null || onSSRMeasure === void 0 ? void 0 : onSSRMeasure({ segmentName, startTimestamp: startTimestampRef.current, endTimestamp: performance.now() }); wasMeasured.current = true; }, [onSSRMeasure, segmentName, startTimestampRef]); return /*#__PURE__*/React.createElement(React.Fragment, null, children, /*#__PURE__*/React.createElement(RenderMarker, { onRender: handleOnRender })); } const SSRRenderMeasureNoOp = /*#__PURE__*/memo(({ children }) => { return children; }); /** * Component for measuring render performance during Server-Side Rendering (SSR). * * This component wraps content to measure its render duration in SSR mode. * On client builds, it's optimized to a no-op component with zero performance overhead. * On SSR builds, it captures timing data and reports it via the `onSSRMeasure` callback. * * **How it works:** * - Measures from `startTimestampRef.current` (component start) to when `RenderMarker` is rendered * - Uses `RenderMarker` to detect when the render completes successfully * - Only reports the measurement once (protected by `wasMeasured` ref) * - If child components throw errors during render, the measurement will not be reported * * **Usage pattern:** * 1. Create `startTimestampRef` as the **first line** in your component using `useRef(performance.now())` * 2. Wrap your content with `SSRRenderMeasure` at the end of your component * 3. Provide the `onSSRMeasure` callback to receive timing data * * @example * ```tsx * function FullPageEditor({ onSSRMeasure }) { * // CRITICAL: Must be the first line for accurate timing * const startTimestampRef = useRef(performance.now()); * * // ...component logic, hooks, etc. * * return ( * <SSRRenderMeasure * segmentName="ssr-app/render/fullPageEditor" * startTimestampRef={startTimestampRef} * onSSRMeasure={onSSRMeasure} * > * <EditorContent /> * </SSRRenderMeasure> * ); * } * ``` * * @example * ```tsx * // Handling the measurement callback * const handleSSRMeasure = (measure) => { * const duration = measure.endTimestamp - measure.startTimestamp; * console.log(`${measure.segmentName} rendered in ${duration}ms`); * // Send to analytics, logging, etc. * }; * ``` */ export const SSRRenderMeasure = isSSR() ? SSRRenderMeasureImpl : SSRRenderMeasureNoOp;