feat: 添加 React 性能追踪 Hooks (usePerformanceTracker)
- usePerformanceTracker: 自动追踪组件渲染性能(mount/rendered/unmount) - usePerformanceMark: 手动标记自定义操作的性能 - 基于 performanceMonitor.ts 封装,提供 React 友好的 API - 完整 TypeScript 类型支持 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
129
src/hooks/usePerformanceTracker.ts
Normal file
129
src/hooks/usePerformanceTracker.ts
Normal file
@@ -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 <div>...</div>;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* 自动标记:
|
||||
* - {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 <button onClick={handleFetch}>加载数据</button>;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
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;
|
||||
Reference in New Issue
Block a user