import React, { useState, useEffect, useCallback } from 'react'; import { Card, Button, Table, Progress, Alert, Space, Typography, Divider } from '@/shared/antd-imports'; import { performanceMonitor } from '@/utils/performance-monitor'; const { Title, Text } = Typography; interface PerformanceAnalysisProps { projectId: string; } const PerformanceAnalysis: React.FC = ({ projectId }) => { const [isMonitoring, setIsMonitoring] = useState(false); const [metrics, setMetrics] = useState({}); const [report, setReport] = useState(''); const [stopMonitoring, setStopMonitoring] = useState<(() => void) | null>(null); // Start monitoring const startMonitoring = useCallback(() => { setIsMonitoring(true); // Start all monitoring const stopFrameRate = performanceMonitor.startFrameRateMonitoring(); const stopLongTasks = performanceMonitor.startLongTaskMonitoring(); const stopLayoutThrashing = performanceMonitor.startLayoutThrashingMonitoring(); // Set up periodic memory monitoring const memoryInterval = setInterval(() => { performanceMonitor.monitorMemory(); }, 1000); // Set up periodic metrics update const metricsInterval = setInterval(() => { setMetrics(performanceMonitor.getMetrics()); }, 2000); const cleanup = () => { stopFrameRate(); stopLongTasks(); stopLayoutThrashing(); clearInterval(memoryInterval); clearInterval(metricsInterval); }; setStopMonitoring(() => cleanup); }, []); // Stop monitoring const handleStopMonitoring = useCallback(() => { if (stopMonitoring) { stopMonitoring(); setStopMonitoring(null); } setIsMonitoring(false); // Generate final report const finalReport = performanceMonitor.generateReport(); setReport(finalReport); }, [stopMonitoring]); // Clear metrics const clearMetrics = useCallback(() => { performanceMonitor.clear(); setMetrics({}); setReport(''); }, []); // Download report const downloadReport = useCallback(() => { if (report) { const blob = new Blob([report], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `performance-report-${projectId}-${new Date().toISOString()}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } }, [report, projectId]); // Cleanup on unmount useEffect(() => { return () => { if (stopMonitoring) { stopMonitoring(); } }; }, [stopMonitoring]); // Prepare table data const tableData = Object.entries(metrics).map(([key, value]: [string, any]) => ({ key, metric: key, average: value.average.toFixed(2), count: value.count, min: value.min.toFixed(2), max: value.max.toFixed(2), status: getMetricStatus(key, value.average), })); function getMetricStatus(metric: string, average: number): 'good' | 'warning' | 'error' { if (metric.includes('render-time')) { return average > 16 ? 'error' : average > 8 ? 'warning' : 'good'; } if (metric === 'fps') { return average < 30 ? 'error' : average < 55 ? 'warning' : 'good'; } if (metric.includes('memory-used') && metric.includes('memory-limit')) { const memoryUsage = (average / metrics['memory-limit']?.average) * 100; return memoryUsage > 80 ? 'error' : memoryUsage > 50 ? 'warning' : 'good'; } return 'good'; } const columns = [ { title: 'Metric', dataIndex: 'metric', key: 'metric', render: (text: string) => ( {text} ), }, { title: 'Average', dataIndex: 'average', key: 'average', render: (text: string, record: any) => { const color = record.status === 'error' ? '#ff4d4f' : record.status === 'warning' ? '#faad14' : '#52c41a'; return {text}; }, }, { title: 'Count', dataIndex: 'count', key: 'count', }, { title: 'Min', dataIndex: 'min', key: 'min', }, { title: 'Max', dataIndex: 'max', key: 'max', }, { title: 'Status', dataIndex: 'status', key: 'status', render: (status: string) => { const color = status === 'error' ? '#ff4d4f' : status === 'warning' ? '#faad14' : '#52c41a'; const text = status === 'error' ? 'Poor' : status === 'warning' ? 'Fair' : 'Good'; return {text}; }, }, ]; return ( {!isMonitoring ? ( ) : ( )} {report && } } > {isMonitoring && ( )} {Object.keys(metrics).length > 0 && ( <> Performance Metrics Key Performance Indicators
{metrics.fps && ( Frame Rate
{metrics.fps.average.toFixed(1)} FPS
)} {metrics['memory-used'] && metrics['memory-limit'] && ( Memory Usage
{( (metrics['memory-used'].average / metrics['memory-limit'].average) * 100 ).toFixed(1)} %
80 ? 'exception' : 'active' } />
)} {metrics['layout-thrashing-count'] && ( Layout Thrashing
10 ? '#ff4d4f' : '#52c41a', }} > {metrics['layout-thrashing-count'].count}
Detected instances
)} {metrics['long-task-duration'] && ( Long Tasks
0 ? '#ff4d4f' : '#52c41a', }} > {metrics['long-task-duration'].count}
Tasks > 50ms
)}
)} {report && ( <> Performance Report
            {report}
          
)} ); }; export default PerformanceAnalysis;