// performance-manager.ts — Performance monitoring and optimization system // TypeScript rewrite with proper type safety class PerformanceManager { constructor() { this.frameTimes = []; this.maxFrameHistory = 60; this.lastFrameTime = 0; this.fps = 60; this.memoryWarnings = 0; this.renderQuality = 1.0; this.adaptiveMode = false; this.setupMonitoring(); } setupMonitoring() { let lastTime = performance.now(); let frameCount = 0; const monitorLoop = (currentTime) => { frameCount++; if (frameCount % 10 === 0) { const delta = currentTime - lastTime; const avgFrameTime = delta / 10; this.fps = Math.round(1000 / avgFrameTime); this.frameTimes.push(avgFrameTime); if (this.frameTimes.length > this.maxFrameHistory) { this.frameTimes.shift(); } this.analyzePerformance(); lastTime = currentTime; } requestAnimationFrame(monitorLoop); }; requestAnimationFrame(monitorLoop); if (window.performance && performance.memory) { setInterval(() => this.checkMemory(), 2000); } } analyzePerformance() { if (this.frameTimes.length < 10) return; const sorted = [...this.frameTimes].sort((a, b) => a - b); const avgFrameTime = sorted.reduce((a, b) => a + b, 0) / sorted.length; const p90FrameTime = sorted[Math.floor(sorted.length * 0.9)]; const frameBudget = 16; // 16ms for 60fps if (p90FrameTime > frameBudget * 1.5) { this.setRenderQuality(Math.max(0.5, this.renderQuality - 0.2)); this.adaptiveMode = true; } else if (p90FrameTime > frameBudget * 1.2) { this.setRenderQuality(Math.max(0.7, this.renderQuality - 0.1)); } else if (avgFrameTime < frameBudget * 0.8 && this.adaptiveMode) { this.setRenderQuality(Math.min(1.0, this.renderQuality + 0.05)); if (this.renderQuality >= 0.95) { this.adaptiveMode = false; } } } checkMemory() { try { // Use type assertion for non-standard memory API const perf = performance; const memory = perf.memory; if (!memory) { throw new Error('Memory API not available'); } const usedHeap = memory.usedJSHeapSize; const heapLimit = memory.jsHeapSizeLimit; const usageRatio = usedHeap / heapLimit; if (usageRatio > 0.8) { this.memoryWarnings++; if (this.memoryWarnings > 3) { this.triggerMemoryCleanup(); this.memoryWarnings = 0; } this.setRenderQuality(Math.max(0.6, this.renderQuality - 0.1)); } else { this.memoryWarnings = Math.max(0, this.memoryWarnings - 0.5); } } catch (e) { console.warn('Memory monitoring not available:', e); } } triggerMemoryCleanup() { if (window.gc) { window.gc(); } } setRenderQuality(quality) { this.renderQuality = Math.max(0.3, Math.min(1.0, quality)); console.debug(`[Perf] Render quality adjusted to: ${(this.renderQuality * 100).toFixed(0)}%`); } getCurrentQuality() { return this.renderQuality; } isPerformanceCritical() { return this.adaptiveMode || this.fps < 45; } getPerformanceStats() { return { fps: this.fps, avgFrameTime: this.frameTimes.length > 0 ? this.frameTimes.reduce((a, b) => a + b, 0) / this.frameTimes.length : 0, renderQuality: this.renderQuality, adaptiveMode: this.adaptiveMode }; } cleanup() { this.frameTimes = []; } } export { PerformanceManager }; //# sourceMappingURL=performance-manager.js.map