From 4a5cd891bd9040f2de195c0f25e3f6e94e5f35bf Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Mon, 8 Dec 2025 17:30:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20React=20=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E8=BF=BD=E8=B8=AA=20Hooks=20(usePerformanceTracker)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - usePerformanceTracker: 自动追踪组件渲染性能(mount/rendered/unmount) - usePerformanceMark: 手动标记自定义操作的性能 - 基于 performanceMonitor.ts 封装,提供 React 友好的 API - 完整 TypeScript 类型支持 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/hooks/usePerformanceTracker.ts | 129 +++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 src/hooks/usePerformanceTracker.ts diff --git a/src/hooks/usePerformanceTracker.ts b/src/hooks/usePerformanceTracker.ts new file mode 100644 index 00000000..6d2fcf79 --- /dev/null +++ b/src/hooks/usePerformanceTracker.ts @@ -0,0 +1,129 @@ +/** + * 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;