/** * React 性能追踪 Hooks * 封装 performanceMonitor 工具,提供 React 友好的性能追踪 API */ import { useEffect, useRef, useCallback } from 'react'; import { performanceMonitor } from '@utils/performanceMonitor'; /** * usePerformanceMark 返回值类型 */ export interface UsePerformanceMarkReturn { /** 标记时间点 */ mark: (suffix: string) => void; /** 测量并记录到 performanceMonitor */ measure: (startSuffix: string, endSuffix: string, name?: string) => number | null; /** 获取测量值(不记录) */ getMeasure: (startSuffix: string, endSuffix: string) => number | null; } /** * usePerformanceTracker - 自动追踪组件渲染性能 * * @param componentName - 组件名称,用于标记 * @param options - 配置选项 * * @example * ```tsx * function MyComponent() { * usePerformanceTracker('MyComponent'); * return
...
; * } * ``` * * 自动标记: * - {componentName}-mount: 组件挂载时 * - {componentName}-rendered: 首次渲染完成 * - {componentName}-unmount: 组件卸载时 */ export function usePerformanceTracker( componentName: string, options: { trackRender?: boolean } = {} ): void { const { trackRender = true } = options; const hasMounted = useRef(false); // 首次渲染时立即标记(同步) if (!hasMounted.current) { performanceMonitor.mark(`${componentName}-mount`); } useEffect(() => { if (!hasMounted.current) { hasMounted.current = true; // 渲染完成标记(在 useEffect 中,表示 DOM 已更新) if (trackRender) { performanceMonitor.mark(`${componentName}-rendered`); performanceMonitor.measure( `${componentName}-mount`, `${componentName}-rendered`, `${componentName} 渲染` ); } } // 组件卸载时标记 return () => { performanceMonitor.mark(`${componentName}-unmount`); }; }, [componentName, trackRender]); } /** * usePerformanceMark - 手动标记自定义操作的性能 * * @param prefix - 标记前缀,用于区分不同操作 * @returns 包含 mark、measure、getMeasure 方法的对象 * * @example * ```tsx * function MyComponent() { * const { mark, getMeasure } = usePerformanceMark('api-call'); * * const handleFetch = async () => { * mark('start'); * await fetchData(); * mark('end'); * const duration = getMeasure('start', 'end'); * console.log('API耗时:', duration, 'ms'); * }; * * return ; * } * ``` */ export function usePerformanceMark(prefix: string): UsePerformanceMarkReturn { const mark = useCallback( (suffix: string) => { performanceMonitor.mark(`${prefix}-${suffix}`); }, [prefix] ); const measure = useCallback( (startSuffix: string, endSuffix: string, name?: string) => { return performanceMonitor.measure( `${prefix}-${startSuffix}`, `${prefix}-${endSuffix}`, name || `${prefix}: ${startSuffix} → ${endSuffix}` ); }, [prefix] ); const getMeasure = useCallback( (startSuffix: string, endSuffix: string) => { return performanceMonitor.measure( `${prefix}-${startSuffix}`, `${prefix}-${endSuffix}` ); }, [prefix] ); return { mark, measure, getMeasure }; } export default usePerformanceTracker;