8.1 性能监控和分析

8.1.1 性能监控系统

在 Sciter-JS 应用中,性能监控是确保应用流畅运行的关键。我们需要建立完善的性能监控体系。

graph TB
    A[性能监控系统] --> B[渲染性能监控]
    A --> C[内存使用监控]
    A --> D[网络请求监控]
    A --> E[用户交互监控]
    
    B --> F[FPS 监控]
    B --> G[渲染时间]
    B --> H[重绘重排]
    
    C --> I[内存占用]
    C --> J[内存泄漏检测]
    C --> K[垃圾回收]
    
    D --> L[请求延迟]
    D --> M[请求成功率]
    D --> N[数据传输量]
    
    E --> O[响应时间]
    E --> P[交互延迟]
    E --> Q[用户体验指标]
// 性能监控器
class PerformanceMonitor {
    constructor(options = {}) {
        this.options = {
            enableFPSMonitor: true,
            enableMemoryMonitor: true,
            enableNetworkMonitor: true,
            enableUserInteractionMonitor: true,
            reportInterval: 5000, // 5秒报告一次
            ...options
        };
        
        this.metrics = {
            fps: [],
            memory: [],
            network: [],
            interactions: []
        };
        
        this.observers = [];
        this.isMonitoring = false;
        
        this.init();
    }
    
    init() {
        if (this.options.enableFPSMonitor) {
            this.initFPSMonitor();
        }
        
        if (this.options.enableMemoryMonitor) {
            this.initMemoryMonitor();
        }
        
        if (this.options.enableNetworkMonitor) {
            this.initNetworkMonitor();
        }
        
        if (this.options.enableUserInteractionMonitor) {
            this.initUserInteractionMonitor();
        }
    }
    
    // FPS 监控
    initFPSMonitor() {
        let lastTime = performance.now();
        let frameCount = 0;
        let fps = 0;
        
        const measureFPS = (currentTime) => {
            frameCount++;
            
            if (currentTime - lastTime >= 1000) {
                fps = Math.round((frameCount * 1000) / (currentTime - lastTime));
                
                this.recordMetric('fps', {
                    value: fps,
                    timestamp: currentTime
                });
                
                frameCount = 0;
                lastTime = currentTime;
            }
            
            if (this.isMonitoring) {
                requestAnimationFrame(measureFPS);
            }
        };
        
        this.fpsMonitor = measureFPS;
    }
    
    // 内存监控
    initMemoryMonitor() {
        this.memoryMonitor = () => {
            if (performance.memory) {
                const memory = {
                    used: performance.memory.usedJSHeapSize,
                    total: performance.memory.totalJSHeapSize,
                    limit: performance.memory.jsHeapSizeLimit,
                    timestamp: performance.now()
                };
                
                this.recordMetric('memory', memory);
                
                // 检测内存泄漏
                this.detectMemoryLeak(memory);
            }
        };
    }
    
    // 网络监控
    initNetworkMonitor() {
        // 监控 XMLHttpRequest
        const originalXHR = window.XMLHttpRequest;
        const self = this;
        
        window.XMLHttpRequest = function() {
            const xhr = new originalXHR();
            const startTime = performance.now();
            
            const originalOpen = xhr.open;
            const originalSend = xhr.send;
            
            let method, url;
            
            xhr.open = function(m, u, ...args) {
                method = m;
                url = u;
                return originalOpen.apply(this, [m, u, ...args]);
            };
            
            xhr.send = function(data) {
                const sendTime = performance.now();
                
                xhr.addEventListener('loadend', () => {
                    const endTime = performance.now();
                    const duration = endTime - sendTime;
                    
                    self.recordMetric('network', {
                        method,
                        url,
                        status: xhr.status,
                        duration,
                        size: xhr.responseText ? xhr.responseText.length : 0,
                        timestamp: endTime
                    });
                });
                
                return originalSend.apply(this, arguments);
            };
            
            return xhr;
        };
    }
    
    // 用户交互监控
    initUserInteractionMonitor() {
        const interactionEvents = ['click', 'keydown', 'scroll', 'touchstart'];
        
        interactionEvents.forEach(eventType => {
            document.addEventListener(eventType, (event) => {
                const startTime = performance.now();
                
                // 使用 setTimeout 来测量事件处理后的响应时间
                setTimeout(() => {
                    const responseTime = performance.now() - startTime;
                    
                    this.recordMetric('interactions', {
                        type: eventType,
                        target: event.target.tagName,
                        responseTime,
                        timestamp: startTime
                    });
                }, 0);
            }, { passive: true });
        });
    }
    
    // 记录指标
    recordMetric(type, data) {
        if (!this.metrics[type]) {
            this.metrics[type] = [];
        }
        
        this.metrics[type].push(data);
        
        // 限制数据量,只保留最近的数据
        if (this.metrics[type].length > 1000) {
            this.metrics[type] = this.metrics[type].slice(-500);
        }
        
        // 触发观察者
        this.notifyObservers(type, data);
    }
    
    // 检测内存泄漏
    detectMemoryLeak(currentMemory) {
        const memoryHistory = this.metrics.memory;
        if (memoryHistory.length < 10) return;
        
        // 检查最近10次内存使用是否持续增长
        const recent = memoryHistory.slice(-10);
        let increasingCount = 0;
        
        for (let i = 1; i < recent.length; i++) {
            if (recent[i].used > recent[i-1].used) {
                increasingCount++;
            }
        }
        
        // 如果80%的时间内存都在增长,可能存在内存泄漏
        if (increasingCount >= 8) {
            this.notifyObservers('memoryLeak', {
                severity: 'warning',
                message: '检测到可能的内存泄漏',
                currentUsage: currentMemory.used,
                timestamp: currentMemory.timestamp
            });
        }
    }
    
    // 开始监控
    start() {
        this.isMonitoring = true;
        
        if (this.fpsMonitor) {
            requestAnimationFrame(this.fpsMonitor);
        }
        
        if (this.memoryMonitor) {
            this.memoryInterval = setInterval(this.memoryMonitor, 1000);
        }
        
        // 定期报告
        this.reportInterval = setInterval(() => {
            this.generateReport();
        }, this.options.reportInterval);
        
        console.log('性能监控已启动');
    }
    
    // 停止监控
    stop() {
        this.isMonitoring = false;
        
        if (this.memoryInterval) {
            clearInterval(this.memoryInterval);
        }
        
        if (this.reportInterval) {
            clearInterval(this.reportInterval);
        }
        
        console.log('性能监控已停止');
    }
    
    // 添加观察者
    addObserver(callback) {
        this.observers.push(callback);
    }
    
    // 移除观察者
    removeObserver(callback) {
        const index = this.observers.indexOf(callback);
        if (index > -1) {
            this.observers.splice(index, 1);
        }
    }
    
    // 通知观察者
    notifyObservers(type, data) {
        this.observers.forEach(callback => {
            try {
                callback(type, data);
            } catch (error) {
                console.error('性能监控观察者错误:', error);
            }
        });
    }
    
    // 生成性能报告
    generateReport() {
        const report = {
            timestamp: Date.now(),
            fps: this.calculateFPSStats(),
            memory: this.calculateMemoryStats(),
            network: this.calculateNetworkStats(),
            interactions: this.calculateInteractionStats()
        };
        
        this.notifyObservers('report', report);
        return report;
    }
    
    // 计算 FPS 统计
    calculateFPSStats() {
        const fpsData = this.metrics.fps.slice(-60); // 最近60秒
        if (fpsData.length === 0) return null;
        
        const values = fpsData.map(d => d.value);
        return {
            current: values[values.length - 1],
            average: Math.round(values.reduce((a, b) => a + b, 0) / values.length),
            min: Math.min(...values),
            max: Math.max(...values)
        };
    }
    
    // 计算内存统计
    calculateMemoryStats() {
        const memoryData = this.metrics.memory.slice(-60);
        if (memoryData.length === 0) return null;
        
        const current = memoryData[memoryData.length - 1];
        const usedValues = memoryData.map(d => d.used);
        
        return {
            current: {
                used: current.used,
                total: current.total,
                usage: Math.round((current.used / current.total) * 100)
            },
            average: Math.round(usedValues.reduce((a, b) => a + b, 0) / usedValues.length),
            peak: Math.max(...usedValues)
        };
    }
    
    // 计算网络统计
    calculateNetworkStats() {
        const networkData = this.metrics.network.slice(-100); // 最近100个请求
        if (networkData.length === 0) return null;
        
        const durations = networkData.map(d => d.duration);
        const successCount = networkData.filter(d => d.status >= 200 && d.status < 300).length;
        
        return {
            requestCount: networkData.length,
            averageLatency: Math.round(durations.reduce((a, b) => a + b, 0) / durations.length),
            successRate: Math.round((successCount / networkData.length) * 100),
            totalDataTransferred: networkData.reduce((total, d) => total + d.size, 0)
        };
    }
    
    // 计算交互统计
    calculateInteractionStats() {
        const interactionData = this.metrics.interactions.slice(-100);
        if (interactionData.length === 0) return null;
        
        const responseTimes = interactionData.map(d => d.responseTime);
        
        return {
            interactionCount: interactionData.length,
            averageResponseTime: Math.round(responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length),
            slowInteractions: interactionData.filter(d => d.responseTime > 100).length
        };
    }
    
    // 获取性能指标
    getMetrics(type) {
        return type ? this.metrics[type] : this.metrics;
    }
    
    // 清除指标数据
    clearMetrics(type) {
        if (type) {
            this.metrics[type] = [];
        } else {
            this.metrics = {
                fps: [],
                memory: [],
                network: [],
                interactions: []
            };
        }
    }
}

8.1.2 性能分析工具

// 性能分析器
class PerformanceAnalyzer {
    constructor() {
        this.profiles = new Map();
        this.activeProfiles = new Map();
    }
    
    // 开始性能分析
    startProfile(name, options = {}) {
        const profile = {
            name,
            startTime: performance.now(),
            marks: [],
            measures: [],
            options: {
                trackMemory: true,
                trackDOM: true,
                trackNetwork: true,
                ...options
            }
        };
        
        this.activeProfiles.set(name, profile);
        
        // 记录初始状态
        this.mark(name, 'start');
        
        if (profile.options.trackMemory && performance.memory) {
            profile.initialMemory = {
                used: performance.memory.usedJSHeapSize,
                total: performance.memory.totalJSHeapSize
            };
        }
        
        if (profile.options.trackDOM) {
            profile.initialDOMNodes = document.querySelectorAll('*').length;
        }
        
        console.log(`开始性能分析: ${name}`);
        return profile;
    }
    
    // 结束性能分析
    endProfile(name) {
        const profile = this.activeProfiles.get(name);
        if (!profile) {
            console.warn(`未找到活动的性能分析: ${name}`);
            return null;
        }
        
        profile.endTime = performance.now();
        profile.duration = profile.endTime - profile.startTime;
        
        // 记录结束状态
        this.mark(name, 'end');
        this.measure(name, 'total', 'start', 'end');
        
        if (profile.options.trackMemory && performance.memory) {
            profile.finalMemory = {
                used: performance.memory.usedJSHeapSize,
                total: performance.memory.totalJSHeapSize
            };
            
            profile.memoryDelta = {
                used: profile.finalMemory.used - profile.initialMemory.used,
                total: profile.finalMemory.total - profile.initialMemory.total
            };
        }
        
        if (profile.options.trackDOM) {
            profile.finalDOMNodes = document.querySelectorAll('*').length;
            profile.domNodesDelta = profile.finalDOMNodes - profile.initialDOMNodes;
        }
        
        // 移动到已完成的分析中
        this.profiles.set(name, profile);
        this.activeProfiles.delete(name);
        
        console.log(`性能分析完成: ${name}`, this.formatProfileReport(profile));
        return profile;
    }
    
    // 添加标记
    mark(profileName, markName) {
        const profile = this.activeProfiles.get(profileName);
        if (!profile) return;
        
        const mark = {
            name: markName,
            time: performance.now(),
            relativeTime: performance.now() - profile.startTime
        };
        
        profile.marks.push(mark);
        
        // 使用浏览器的 Performance API
        if (performance.mark) {
            performance.mark(`${profileName}-${markName}`);
        }
        
        return mark;
    }
    
    // 测量时间段
    measure(profileName, measureName, startMark, endMark) {
        const profile = this.activeProfiles.get(profileName) || this.profiles.get(profileName);
        if (!profile) return;
        
        const startMarkObj = profile.marks.find(m => m.name === startMark);
        const endMarkObj = profile.marks.find(m => m.name === endMark);
        
        if (!startMarkObj || !endMarkObj) {
            console.warn(`未找到标记: ${startMark} 或 ${endMark}`);
            return;
        }
        
        const measure = {
            name: measureName,
            startTime: startMarkObj.time,
            endTime: endMarkObj.time,
            duration: endMarkObj.time - startMarkObj.time,
            startMark,
            endMark
        };
        
        profile.measures.push(measure);
        
        // 使用浏览器的 Performance API
        if (performance.measure) {
            try {
                performance.measure(
                    `${profileName}-${measureName}`,
                    `${profileName}-${startMark}`,
                    `${profileName}-${endMark}`
                );
            } catch (error) {
                console.warn('Performance.measure 失败:', error);
            }
        }
        
        return measure;
    }
    
    // 格式化分析报告
    formatProfileReport(profile) {
        const report = {
            name: profile.name,
            duration: `${profile.duration.toFixed(2)}ms`,
            marks: profile.marks.length,
            measures: profile.measures.map(m => ({
                name: m.name,
                duration: `${m.duration.toFixed(2)}ms`
            }))
        };
        
        if (profile.memoryDelta) {
            report.memoryUsage = {
                delta: `${(profile.memoryDelta.used / 1024 / 1024).toFixed(2)}MB`,
                initial: `${(profile.initialMemory.used / 1024 / 1024).toFixed(2)}MB`,
                final: `${(profile.finalMemory.used / 1024 / 1024).toFixed(2)}MB`
            };
        }
        
        if (profile.domNodesDelta !== undefined) {
            report.domNodes = {
                delta: profile.domNodesDelta,
                initial: profile.initialDOMNodes,
                final: profile.finalDOMNodes
            };
        }
        
        return report;
    }
    
    // 获取分析结果
    getProfile(name) {
        return this.profiles.get(name) || this.activeProfiles.get(name);
    }
    
    // 获取所有分析结果
    getAllProfiles() {
        return {
            completed: Array.from(this.profiles.values()),
            active: Array.from(this.activeProfiles.values())
        };
    }
    
    // 清除分析数据
    clearProfiles() {
        this.profiles.clear();
        this.activeProfiles.clear();
        
        // 清除浏览器的 Performance 数据
        if (performance.clearMarks) {
            performance.clearMarks();
        }
        if (performance.clearMeasures) {
            performance.clearMeasures();
        }
    }
    
    // 导出分析数据
    exportProfiles() {
        const data = {
            timestamp: Date.now(),
            userAgent: navigator.userAgent,
            profiles: this.getAllProfiles()
        };
        
        return JSON.stringify(data, null, 2);
    }
}

// 性能分析装饰器
function performanceProfile(name, options = {}) {
    return function(target, propertyKey, descriptor) {
        const originalMethod = descriptor.value;
        
        descriptor.value = async function(...args) {
            const analyzer = window.performanceAnalyzer || new PerformanceAnalyzer();
            
            const profileName = `${target.constructor.name}.${propertyKey}-${name || Date.now()}`;
            analyzer.startProfile(profileName, options);
            
            try {
                const result = await originalMethod.apply(this, args);
                analyzer.endProfile(profileName);
                return result;
            } catch (error) {
                analyzer.endProfile(profileName);
                throw error;
            }
        };
        
        return descriptor;
    };
}

8.2 内存管理和优化

8.2.1 内存泄漏检测和预防

// 内存泄漏检测器
class MemoryLeakDetector {
    constructor(options = {}) {
        this.options = {
            checkInterval: 10000, // 10秒检查一次
            thresholdIncrease: 5 * 1024 * 1024, // 5MB 增长阈值
            consecutiveIncreases: 5, // 连续增长次数阈值
            ...options
        };
        
        this.memoryHistory = [];
        this.leakSuspects = new Set();
        this.isMonitoring = false;
        this.checkInterval = null;
        
        this.setupDOMObserver();
        this.setupEventListenerTracker();
    }
    
    // 开始监控
    startMonitoring() {
        if (this.isMonitoring) return;
        
        this.isMonitoring = true;
        this.checkInterval = setInterval(() => {
            this.checkMemoryUsage();
        }, this.options.checkInterval);
        
        console.log('内存泄漏监控已启动');
    }
    
    // 停止监控
    stopMonitoring() {
        if (!this.isMonitoring) return;
        
        this.isMonitoring = false;
        if (this.checkInterval) {
            clearInterval(this.checkInterval);
            this.checkInterval = null;
        }
        
        console.log('内存泄漏监控已停止');
    }
    
    // 检查内存使用
    checkMemoryUsage() {
        if (!performance.memory) {
            console.warn('浏览器不支持 performance.memory API');
            return;
        }
        
        const currentMemory = {
            used: performance.memory.usedJSHeapSize,
            total: performance.memory.totalJSHeapSize,
            limit: performance.memory.jsHeapSizeLimit,
            timestamp: Date.now()
        };
        
        this.memoryHistory.push(currentMemory);
        
        // 只保留最近的数据
        if (this.memoryHistory.length > 100) {
            this.memoryHistory = this.memoryHistory.slice(-50);
        }
        
        this.analyzeMemoryTrend();
    }
    
    // 分析内存趋势
    analyzeMemoryTrend() {
        if (this.memoryHistory.length < this.options.consecutiveIncreases) {
            return;
        }
        
        const recent = this.memoryHistory.slice(-this.options.consecutiveIncreases);
        let consecutiveIncreases = 0;
        let totalIncrease = 0;
        
        for (let i = 1; i < recent.length; i++) {
            const increase = recent[i].used - recent[i-1].used;
            if (increase > 0) {
                consecutiveIncreases++;
                totalIncrease += increase;
            } else {
                consecutiveIncreases = 0;
                totalIncrease = 0;
            }
        }
        
        // 检测潜在的内存泄漏
        if (consecutiveIncreases >= this.options.consecutiveIncreases - 1 && 
            totalIncrease > this.options.thresholdIncrease) {
            
            this.reportPotentialLeak({
                consecutiveIncreases,
                totalIncrease,
                currentUsage: recent[recent.length - 1].used,
                timespan: recent[recent.length - 1].timestamp - recent[0].timestamp
            });
        }
    }
    
    // 报告潜在泄漏
    reportPotentialLeak(details) {
        const leakReport = {
            type: 'potential_memory_leak',
            timestamp: Date.now(),
            details,
            suspects: this.identifyLeakSuspects(),
            recommendations: this.generateRecommendations()
        };
        
        console.warn('检测到潜在的内存泄漏:', leakReport);
        
        // 触发事件
        if (typeof window !== 'undefined') {
            window.dispatchEvent(new CustomEvent('memoryLeakDetected', {
                detail: leakReport
            }));
        }
        
        return leakReport;
    }
    
    // 识别泄漏嫌疑
    identifyLeakSuspects() {
        const suspects = [];
        
        // 检查 DOM 节点数量
        const domNodeCount = document.querySelectorAll('*').length;
        if (domNodeCount > 10000) {
            suspects.push({
                type: 'excessive_dom_nodes',
                count: domNodeCount,
                description: 'DOM 节点数量过多,可能存在未清理的节点'
            });
        }
        
        // 检查事件监听器
        if (this.eventListenerCount > 1000) {
            suspects.push({
                type: 'excessive_event_listeners',
                count: this.eventListenerCount,
                description: '事件监听器数量过多,可能存在未移除的监听器'
            });
        }
        
        // 检查定时器
        const timerCount = this.getActiveTimerCount();
        if (timerCount > 100) {
            suspects.push({
                type: 'excessive_timers',
                count: timerCount,
                description: '活动定时器数量过多,可能存在未清理的定时器'
            });
        }
        
        return suspects;
    }
    
    // 生成建议
    generateRecommendations() {
        return [
            '检查是否有未移除的事件监听器',
            '确保定时器和间隔器被正确清理',
            '检查是否有循环引用导致的内存泄漏',
            '使用 WeakMap 和 WeakSet 来避免强引用',
            '及时清理不再使用的 DOM 节点',
            '检查闭包中是否持有了不必要的引用'
        ];
    }
    
    // 设置 DOM 观察器
    setupDOMObserver() {
        if (typeof MutationObserver === 'undefined') return;
        
        this.domObserver = new MutationObserver((mutations) => {
            let addedNodes = 0;
            let removedNodes = 0;
            
            mutations.forEach(mutation => {
                addedNodes += mutation.addedNodes.length;
                removedNodes += mutation.removedNodes.length;
            });
            
            // 如果添加的节点远多于移除的节点,可能存在问题
            if (addedNodes > removedNodes + 100) {
                this.leakSuspects.add('dom_nodes_accumulation');
            }
        });
        
        this.domObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    }
    
    // 设置事件监听器跟踪
    setupEventListenerTracker() {
        this.eventListenerCount = 0;
        
        // 重写 addEventListener
        const originalAddEventListener = EventTarget.prototype.addEventListener;
        const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
        
        EventTarget.prototype.addEventListener = function(type, listener, options) {
            this.eventListenerCount = (this.eventListenerCount || 0) + 1;
            return originalAddEventListener.call(this, type, listener, options);
        };
        
        EventTarget.prototype.removeEventListener = function(type, listener, options) {
            this.eventListenerCount = Math.max((this.eventListenerCount || 0) - 1, 0);
            return originalRemoveEventListener.call(this, type, listener, options);
        };
    }
    
    // 获取活动定时器数量(近似值)
    getActiveTimerCount() {
        // 这是一个近似的方法,实际实现可能需要更复杂的跟踪
        return window.activeTimers ? window.activeTimers.size : 0;
    }
    
    // 强制垃圾回收(仅在支持的浏览器中)
    forceGarbageCollection() {
        if (window.gc) {
            window.gc();
            console.log('已触发垃圾回收');
        } else {
            console.warn('浏览器不支持手动垃圾回收');
        }
    }
    
    // 获取内存使用报告
    getMemoryReport() {
        if (!performance.memory) {
            return { error: '浏览器不支持 performance.memory API' };
        }
        
        const current = performance.memory;
        const history = this.memoryHistory;
        
        return {
            current: {
                used: `${(current.usedJSHeapSize / 1024 / 1024).toFixed(2)}MB`,
                total: `${(current.totalJSHeapSize / 1024 / 1024).toFixed(2)}MB`,
                limit: `${(current.jsHeapSizeLimit / 1024 / 1024).toFixed(2)}MB`,
                usage: `${((current.usedJSHeapSize / current.totalJSHeapSize) * 100).toFixed(1)}%`
            },
            trend: history.length > 1 ? {
                direction: history[history.length - 1].used > history[0].used ? 'increasing' : 'decreasing',
                change: `${((history[history.length - 1].used - history[0].used) / 1024 / 1024).toFixed(2)}MB`
            } : null,
            suspects: Array.from(this.leakSuspects),
            recommendations: this.generateRecommendations()
        };
    }
}

8.2.2 内存优化策略

// 内存优化工具
class MemoryOptimizer {
    constructor() {
        this.objectPools = new Map();
        this.weakRefs = new Map();
        this.cleanupTasks = [];
    }
    
    // 对象池管理
    createObjectPool(name, factory, resetFn, initialSize = 10) {
        const pool = {
            name,
            factory,
            resetFn,
            available: [],
            inUse: new Set(),
            totalCreated: 0,
            totalReused: 0
        };
        
        // 预创建对象
        for (let i = 0; i < initialSize; i++) {
            const obj = factory();
            pool.available.push(obj);
            pool.totalCreated++;
        }
        
        this.objectPools.set(name, pool);
        return pool;
    }
    
    // 从对象池获取对象
    getFromPool(poolName) {
        const pool = this.objectPools.get(poolName);
        if (!pool) {
            throw new Error(`对象池 ${poolName} 不存在`);
        }
        
        let obj;
        if (pool.available.length > 0) {
            obj = pool.available.pop();
            pool.totalReused++;
        } else {
            obj = pool.factory();
            pool.totalCreated++;
        }
        
        pool.inUse.add(obj);
        return obj;
    }
    
    // 归还对象到池中
    returnToPool(poolName, obj) {
        const pool = this.objectPools.get(poolName);
        if (!pool) {
            throw new Error(`对象池 ${poolName} 不存在`);
        }
        
        if (!pool.inUse.has(obj)) {
            console.warn('尝试归还不属于此池的对象');
            return;
        }
        
        pool.inUse.delete(obj);
        
        // 重置对象状态
        if (pool.resetFn) {
            pool.resetFn(obj);
        }
        
        pool.available.push(obj);
    }
    
    // 获取对象池统计
    getPoolStats(poolName) {
        const pool = this.objectPools.get(poolName);
        if (!pool) return null;
        
        return {
            name: pool.name,
            available: pool.available.length,
            inUse: pool.inUse.size,
            totalCreated: pool.totalCreated,
            totalReused: pool.totalReused,
            reuseRate: pool.totalReused / (pool.totalCreated + pool.totalReused)
        };
    }
    
    // 弱引用管理
    createWeakRef(key, object, cleanupCallback) {
        if (typeof WeakRef === 'undefined') {
            console.warn('浏览器不支持 WeakRef');
            return object;
        }
        
        const weakRef = new WeakRef(object);
        this.weakRefs.set(key, {
            ref: weakRef,
            cleanup: cleanupCallback
        });
        
        return weakRef;
    }
    
    // 获取弱引用对象
    getWeakRef(key) {
        const entry = this.weakRefs.get(key);
        if (!entry) return null;
        
        const obj = entry.ref.deref();
        if (!obj) {
            // 对象已被垃圾回收
            if (entry.cleanup) {
                entry.cleanup();
            }
            this.weakRefs.delete(key);
            return null;
        }
        
        return obj;
    }
    
    // 清理弱引用
    cleanupWeakRefs() {
        for (const [key, entry] of this.weakRefs) {
            if (!entry.ref.deref()) {
                if (entry.cleanup) {
                    entry.cleanup();
                }
                this.weakRefs.delete(key);
            }
        }
    }
    
    // 注册清理任务
    registerCleanupTask(task, priority = 'normal') {
        this.cleanupTasks.push({
            task,
            priority,
            timestamp: Date.now()
        });
        
        // 按优先级排序
        this.cleanupTasks.sort((a, b) => {
            const priorityOrder = { high: 3, normal: 2, low: 1 };
            return priorityOrder[b.priority] - priorityOrder[a.priority];
        });
    }
    
    // 执行清理任务
    runCleanupTasks() {
        const startTime = performance.now();
        let tasksExecuted = 0;
        
        while (this.cleanupTasks.length > 0) {
            const { task } = this.cleanupTasks.shift();
            
            try {
                task();
                tasksExecuted++;
            } catch (error) {
                console.error('清理任务执行失败:', error);
            }
            
            // 限制执行时间,避免阻塞主线程
            if (performance.now() - startTime > 16) { // 16ms
                break;
            }
        }
        
        console.log(`执行了 ${tasksExecuted} 个清理任务,耗时 ${(performance.now() - startTime).toFixed(2)}ms`);
    }
    
    // 内存压力检测
    detectMemoryPressure() {
        if (!performance.memory) {
            return 'unknown';
        }
        
        const { usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit } = performance.memory;
        const usageRatio = usedJSHeapSize / totalJSHeapSize;
        const limitRatio = totalJSHeapSize / jsHeapSizeLimit;
        
        if (usageRatio > 0.9 || limitRatio > 0.8) {
            return 'high';
        } else if (usageRatio > 0.7 || limitRatio > 0.6) {
            return 'medium';
        } else {
            return 'low';
        }
    }
    
    // 自动内存管理
    enableAutoMemoryManagement(options = {}) {
        const config = {
            cleanupInterval: 30000, // 30秒
            pressureCheckInterval: 5000, // 5秒
            aggressiveCleanupThreshold: 'high',
            ...options
        };
        
        // 定期清理
        setInterval(() => {
            this.runCleanupTasks();
            this.cleanupWeakRefs();
        }, config.cleanupInterval);
        
        // 内存压力检测
        setInterval(() => {
            const pressure = this.detectMemoryPressure();
            
            if (pressure === config.aggressiveCleanupThreshold) {
                console.log('检测到内存压力,执行积极清理');
                this.runCleanupTasks();
                this.cleanupWeakRefs();
                
                // 清理对象池中的空闲对象
                this.cleanupObjectPools();
            }
        }, config.pressureCheckInterval);
        
        console.log('自动内存管理已启用');
    }
    
    // 清理对象池
    cleanupObjectPools() {
        for (const [name, pool] of this.objectPools) {
            // 保留一半的空闲对象
            const keepCount = Math.ceil(pool.available.length / 2);
            pool.available = pool.available.slice(0, keepCount);
        }
    }
    
    // 获取内存优化报告
    getOptimizationReport() {
        const poolStats = Array.from(this.objectPools.keys()).map(name => 
            this.getPoolStats(name)
        );
        
        return {
            timestamp: Date.now(),
            memoryPressure: this.detectMemoryPressure(),
            objectPools: poolStats,
            weakRefs: this.weakRefs.size,
            pendingCleanupTasks: this.cleanupTasks.length,
            totalPoolReuse: poolStats.reduce((total, pool) => 
                total + (pool.reuseRate || 0), 0
            ) / poolStats.length
        };
    }
}

8.3 渲染性能优化

8.3.1 渲染优化策略

// 渲染优化器
class RenderOptimizer {
    constructor() {
        this.frameScheduler = new FrameScheduler();
        this.virtualScrollManager = new VirtualScrollManager();
        this.batchUpdater = new BatchUpdater();
        this.renderCache = new Map();
    }
    
    // 批量 DOM 更新
    batchDOMUpdates(updates) {
        return this.batchUpdater.batch(() => {
            updates.forEach(update => update());
        });
    }
    
    // 虚拟滚动
    enableVirtualScroll(container, options) {
        return this.virtualScrollManager.enable(container, options);
    }
    
    // 渲染缓存
    cacheRender(key, renderFn, dependencies = []) {
        const cacheKey = this.generateCacheKey(key, dependencies);
        
        if (this.renderCache.has(cacheKey)) {
            return this.renderCache.get(cacheKey);
        }
        
        const result = renderFn();
        this.renderCache.set(cacheKey, result);
        
        return result;
    }
    
    generateCacheKey(key, dependencies) {
        const depHash = dependencies.map(dep => 
            typeof dep === 'object' ? JSON.stringify(dep) : String(dep)
        ).join('|');
        
        return `${key}:${depHash}`;
    }
    
    // 清除渲染缓存
    clearRenderCache(pattern) {
        if (pattern) {
            const regex = new RegExp(pattern);
            for (const [key] of this.renderCache) {
                if (regex.test(key)) {
                    this.renderCache.delete(key);
                }
            }
        } else {
            this.renderCache.clear();
        }
    }
}

// 帧调度器
class FrameScheduler {
    constructor() {
        this.tasks = [];
        this.isRunning = false;
        this.frameDeadline = 16; // 16ms per frame
    }
    
    // 调度任务
    schedule(task, priority = 'normal') {
        this.tasks.push({
            task,
            priority,
            timestamp: performance.now()
        });
        
        this.sortTasks();
        
        if (!this.isRunning) {
            this.startFrame();
        }
    }
    
    // 排序任务
    sortTasks() {
        const priorityOrder = { high: 3, normal: 2, low: 1 };
        this.tasks.sort((a, b) => {
            return priorityOrder[b.priority] - priorityOrder[a.priority];
        });
    }
    
    // 开始帧处理
    startFrame() {
        this.isRunning = true;
        requestAnimationFrame(() => this.processFrame());
    }
    
    // 处理帧
    processFrame() {
        const frameStart = performance.now();
        
        while (this.tasks.length > 0 && 
               (performance.now() - frameStart) < this.frameDeadline) {
            
            const { task } = this.tasks.shift();
            
            try {
                task();
            } catch (error) {
                console.error('帧任务执行失败:', error);
            }
        }
        
        if (this.tasks.length > 0) {
            // 还有任务,继续下一帧
            requestAnimationFrame(() => this.processFrame());
        } else {
            this.isRunning = false;
        }
    }
    
    // 获取待处理任务数量
    getPendingTaskCount() {
        return this.tasks.length;
    }
}

// 批量更新器
class BatchUpdater {
    constructor() {
        this.pendingUpdates = [];
        this.isScheduled = false;
    }
    
    // 批量执行
    batch(updateFn) {
        return new Promise((resolve, reject) => {
            this.pendingUpdates.push({ updateFn, resolve, reject });
            
            if (!this.isScheduled) {
                this.scheduleFlush();
            }
        });
    }
    
    // 调度刷新
    scheduleFlush() {
        this.isScheduled = true;
        
        requestAnimationFrame(() => {
            this.flush();
        });
    }
    
    // 刷新更新
    flush() {
        const updates = this.pendingUpdates.splice(0);
        this.isScheduled = false;
        
        // 批量执行所有更新
        updates.forEach(({ updateFn, resolve, reject }) => {
            try {
                const result = updateFn();
                resolve(result);
            } catch (error) {
                reject(error);
            }
        });
    }
}

// 虚拟滚动管理器
class VirtualScrollManager {
    constructor() {
        this.instances = new Map();
    }
    
    // 启用虚拟滚动
    enable(container, options = {}) {
        const config = {
            itemHeight: 50,
            bufferSize: 5,
            threshold: 100,
            ...options
        };
        
        const instance = new VirtualScrollInstance(container, config);
        this.instances.set(container, instance);
        
        return instance;
    }
    
    // 禁用虚拟滚动
    disable(container) {
        const instance = this.instances.get(container);
        if (instance) {
            instance.destroy();
            this.instances.delete(container);
        }
    }
}

// 虚拟滚动实例
class VirtualScrollInstance {
    constructor(container, config) {
        this.container = container;
        this.config = config;
        this.items = [];
        this.visibleItems = [];
        this.scrollTop = 0;
        this.containerHeight = 0;
        
        this.init();
    }
    
    init() {
        this.containerHeight = this.container.clientHeight;
        this.setupScrollListener();
        this.createViewport();
    }
    
    // 设置滚动监听
    setupScrollListener() {
        this.container.addEventListener('scroll', () => {
            this.scrollTop = this.container.scrollTop;
            this.updateVisibleItems();
        }, { passive: true });
    }
    
    // 创建视口
    createViewport() {
        this.viewport = document.createElement('div');
        this.viewport.style.position = 'relative';
        this.container.appendChild(this.viewport);
    }
    
    // 设置数据
    setData(items) {
        this.items = items;
        this.updateTotalHeight();
        this.updateVisibleItems();
    }
    
    // 更新总高度
    updateTotalHeight() {
        const totalHeight = this.items.length * this.config.itemHeight;
        this.viewport.style.height = `${totalHeight}px`;
    }
    
    // 更新可见项
    updateVisibleItems() {
        const startIndex = Math.floor(this.scrollTop / this.config.itemHeight);
        const endIndex = Math.min(
            startIndex + Math.ceil(this.containerHeight / this.config.itemHeight) + this.config.bufferSize,
            this.items.length
        );
        
        const visibleStartIndex = Math.max(0, startIndex - this.config.bufferSize);
        
        this.renderVisibleItems(visibleStartIndex, endIndex);
    }
    
    // 渲染可见项
    renderVisibleItems(startIndex, endIndex) {
        // 清除现有项
        this.viewport.innerHTML = '';
        
        for (let i = startIndex; i < endIndex; i++) {
            const item = this.items[i];
            if (!item) continue;
            
            const element = this.createItemElement(item, i);
            element.style.position = 'absolute';
            element.style.top = `${i * this.config.itemHeight}px`;
            element.style.height = `${this.config.itemHeight}px`;
            
            this.viewport.appendChild(element);
        }
    }
    
    // 创建项元素
    createItemElement(item, index) {
        if (this.config.renderItem) {
            return this.config.renderItem(item, index);
        }
        
        const element = document.createElement('div');
        element.textContent = typeof item === 'string' ? item : JSON.stringify(item);
        return element;
    }
    
    // 销毁
    destroy() {
        if (this.viewport && this.viewport.parentNode) {
            this.viewport.parentNode.removeChild(this.viewport);
        }
    }
}

8.4 调试工具和技巧

8.4.1 调试工具集

// 调试工具集
class DebugToolkit {
    constructor() {
        this.loggers = new Map();
        this.breakpoints = new Set();
        this.watchers = new Map();
        this.isEnabled = false;
        
        this.setupGlobalDebugger();
    }
    
    // 启用调试
    enable() {
        this.isEnabled = true;
        console.log('调试工具已启用');
    }
    
    // 禁用调试
    disable() {
        this.isEnabled = false;
        console.log('调试工具已禁用');
    }
    
    // 创建日志器
    createLogger(name, options = {}) {
        const logger = new DebugLogger(name, {
            level: 'info',
            prefix: `[${name}]`,
            timestamp: true,
            ...options
        });
        
        this.loggers.set(name, logger);
        return logger;
    }
    
    // 获取日志器
    getLogger(name) {
        return this.loggers.get(name);
    }
    
    // 设置断点
    setBreakpoint(condition, message) {
        const breakpoint = {
            id: Date.now(),
            condition,
            message,
            hitCount: 0
        };
        
        this.breakpoints.add(breakpoint);
        return breakpoint.id;
    }
    
    // 检查断点
    checkBreakpoints(context = {}) {
        if (!this.isEnabled) return;
        
        for (const breakpoint of this.breakpoints) {
            try {
                if (typeof breakpoint.condition === 'function') {
                    if (breakpoint.condition(context)) {
                        breakpoint.hitCount++;
                        console.log(`断点触发: ${breakpoint.message}`, context);
                        debugger; // 触发调试器
                    }
                } else if (breakpoint.condition === true) {
                    breakpoint.hitCount++;
                    console.log(`断点触发: ${breakpoint.message}`, context);
                    debugger;
                }
            } catch (error) {
                console.error('断点条件执行失败:', error);
            }
        }
    }
    
    // 移除断点
    removeBreakpoint(id) {
        for (const breakpoint of this.breakpoints) {
            if (breakpoint.id === id) {
                this.breakpoints.delete(breakpoint);
                return true;
            }
        }
        return false;
    }
    
    // 添加监视器
    addWatcher(name, getter, options = {}) {
        const watcher = {
            name,
            getter,
            previousValue: undefined,
            changeCount: 0,
            options: {
                logChanges: true,
                breakOnChange: false,
                ...options
            }
        };
        
        this.watchers.set(name, watcher);
        
        // 立即获取初始值
        try {
            watcher.previousValue = getter();
        } catch (error) {
            console.error(`监视器 ${name} 初始化失败:`, error);
        }
        
        return watcher;
    }
    
    // 检查监视器
    checkWatchers() {
        if (!this.isEnabled) return;
        
        for (const [name, watcher] of this.watchers) {
            try {
                const currentValue = watcher.getter();
                
                if (currentValue !== watcher.previousValue) {
                    watcher.changeCount++;
                    
                    if (watcher.options.logChanges) {
                        console.log(`监视器 ${name} 值变化:`, {
                            from: watcher.previousValue,
                            to: currentValue,
                            changeCount: watcher.changeCount
                        });
                    }
                    
                    if (watcher.options.breakOnChange) {
                        console.log(`监视器 ${name} 触发断点`);
                        debugger;
                    }
                    
                    watcher.previousValue = currentValue;
                }
            } catch (error) {
                console.error(`监视器 ${name} 检查失败:`, error);
            }
        }
    }
    
    // 移除监视器
    removeWatcher(name) {
        return this.watchers.delete(name);
    }
    
    // 设置全局调试器
    setupGlobalDebugger() {
        // 全局错误处理
        window.addEventListener('error', (event) => {
            if (this.isEnabled) {
                console.error('全局错误:', {
                    message: event.message,
                    filename: event.filename,
                    lineno: event.lineno,
                    colno: event.colno,
                    error: event.error
                });
            }
        });
        
        // 未处理的 Promise 拒绝
        window.addEventListener('unhandledrejection', (event) => {
            if (this.isEnabled) {
                console.error('未处理的 Promise 拒绝:', event.reason);
            }
        });
        
        // 定期检查监视器
        setInterval(() => {
            this.checkWatchers();
        }, 1000);
    }
    
    // 性能分析
    profile(name, fn) {
        if (!this.isEnabled) {
            return fn();
        }
        
        console.time(name);
        console.profile(name);
        
        try {
            const result = fn();
            
            if (result && typeof result.then === 'function') {
                return result.finally(() => {
                    console.timeEnd(name);
                    console.profileEnd(name);
                });
            } else {
                console.timeEnd(name);
                console.profileEnd(name);
                return result;
            }
        } catch (error) {
            console.timeEnd(name);
            console.profileEnd(name);
            throw error;
        }
    }
    
    // 内存快照
    takeMemorySnapshot() {
        if (!performance.memory) {
            console.warn('浏览器不支持内存 API');
            return null;
        }
        
        const snapshot = {
            timestamp: Date.now(),
            memory: {
                used: performance.memory.usedJSHeapSize,
                total: performance.memory.totalJSHeapSize,
                limit: performance.memory.jsHeapSizeLimit
            },
            dom: {
                nodes: document.querySelectorAll('*').length,
                listeners: this.estimateEventListeners()
            }
        };
        
        console.log('内存快照:', snapshot);
        return snapshot;
    }
    
    // 估算事件监听器数量
    estimateEventListeners() {
        // 这是一个简化的估算方法
        let count = 0;
        const elements = document.querySelectorAll('*');
        
        elements.forEach(element => {
            // 检查常见的事件属性
            const eventAttrs = ['onclick', 'onload', 'onchange', 'onsubmit'];
            eventAttrs.forEach(attr => {
                if (element[attr]) count++;
            });
        });
        
        return count;
    }
    
    // 获取调试报告
    getDebugReport() {
        return {
            timestamp: Date.now(),
            enabled: this.isEnabled,
            loggers: Array.from(this.loggers.keys()),
            breakpoints: Array.from(this.breakpoints).map(bp => ({
                id: bp.id,
                message: bp.message,
                hitCount: bp.hitCount
            })),
            watchers: Array.from(this.watchers.entries()).map(([name, watcher]) => ({
                name,
                changeCount: watcher.changeCount,
                currentValue: watcher.previousValue
            }))
        };
    }
}

// 调试日志器
class DebugLogger {
    constructor(name, options = {}) {
        this.name = name;
        this.options = {
            level: 'info',
            prefix: `[${name}]`,
            timestamp: true,
            colors: {
                error: '#ff4444',
                warn: '#ffaa00',
                info: '#4444ff',
                debug: '#888888'
            },
            ...options
        };
        
        this.logs = [];
        this.maxLogs = 1000;
    }
    
    // 记录日志
    log(level, message, ...args) {
        const logEntry = {
            timestamp: Date.now(),
            level,
            message,
            args,
            stack: new Error().stack
        };
        
        this.logs.push(logEntry);
        
        // 限制日志数量
        if (this.logs.length > this.maxLogs) {
            this.logs = this.logs.slice(-this.maxLogs / 2);
        }
        
        // 输出到控制台
        this.outputToConsole(logEntry);
    }
    
    // 输出到控制台
    outputToConsole(logEntry) {
        const { timestamp, level, message, args } = logEntry;
        
        let prefix = this.options.prefix;
        if (this.options.timestamp) {
            const time = new Date(timestamp).toLocaleTimeString();
            prefix = `${time} ${prefix}`;
        }
        
        const color = this.options.colors[level] || '#000000';
        const style = `color: ${color}; font-weight: bold;`;
        
        switch (level) {
            case 'error':
                console.error(`%c${prefix}`, style, message, ...args);
                break;
            case 'warn':
                console.warn(`%c${prefix}`, style, message, ...args);
                break;
            case 'info':
                console.info(`%c${prefix}`, style, message, ...args);
                break;
            case 'debug':
                console.debug(`%c${prefix}`, style, message, ...args);
                break;
            default:
                console.log(`%c${prefix}`, style, message, ...args);
        }
    }
    
    // 便捷方法
    error(message, ...args) {
        this.log('error', message, ...args);
    }
    
    warn(message, ...args) {
        this.log('warn', message, ...args);
    }
    
    info(message, ...args) {
        this.log('info', message, ...args);
    }
    
    debug(message, ...args) {
        this.log('debug', message, ...args);
    }
    
    // 获取日志历史
    getHistory(level) {
        if (level) {
            return this.logs.filter(log => log.level === level);
        }
        return this.logs;
    }
    
    // 清除日志
    clear() {
        this.logs = [];
    }
    
    // 导出日志
    export() {
        return {
            name: this.name,
            timestamp: Date.now(),
            logs: this.logs
        };
    }
}

8.4.2 错误处理和异常监控

// 错误监控系统
class ErrorMonitor {
    constructor(options = {}) {
        this.options = {
            maxErrors: 100,
            reportEndpoint: null,
            enableStackTrace: true,
            enableUserAgent: true,
            enableURL: true,
            ...options
        };
        
        this.errors = [];
        this.errorCounts = new Map();
        this.isEnabled = false;
        
        this.setupErrorHandlers();
    }
    
    // 启用错误监控
    enable() {
        this.isEnabled = true;
        console.log('错误监控已启用');
    }
    
    // 禁用错误监控
    disable() {
        this.isEnabled = false;
        console.log('错误监控已禁用');
    }
    
    // 设置错误处理器
    setupErrorHandlers() {
        // JavaScript 错误
        window.addEventListener('error', (event) => {
            if (this.isEnabled) {
                this.recordError({
                    type: 'javascript',
                    message: event.message,
                    filename: event.filename,
                    lineno: event.lineno,
                    colno: event.colno,
                    error: event.error,
                    stack: event.error ? event.error.stack : null
                });
            }
        });
        
        // Promise 拒绝
        window.addEventListener('unhandledrejection', (event) => {
            if (this.isEnabled) {
                this.recordError({
                    type: 'promise',
                    message: event.reason ? event.reason.toString() : 'Promise rejected',
                    reason: event.reason,
                    stack: event.reason && event.reason.stack ? event.reason.stack : null
                });
            }
        });
        
        // 资源加载错误
        window.addEventListener('error', (event) => {
            if (this.isEnabled && event.target !== window) {
                this.recordError({
                    type: 'resource',
                    message: `Failed to load resource: ${event.target.src || event.target.href}`,
                    element: event.target.tagName,
                    source: event.target.src || event.target.href
                });
            }
        }, true);
    }
    
    // 记录错误
    recordError(errorInfo) {
        const error = {
            id: Date.now() + Math.random(),
            timestamp: Date.now(),
            url: window.location.href,
            userAgent: navigator.userAgent,
            ...errorInfo
        };
        
        this.errors.push(error);
        
        // 限制错误数量
        if (this.errors.length > this.options.maxErrors) {
            this.errors = this.errors.slice(-this.options.maxErrors / 2);
        }
        
        // 统计错误次数
        const errorKey = this.getErrorKey(error);
        this.errorCounts.set(errorKey, (this.errorCounts.get(errorKey) || 0) + 1);
        
        // 输出错误信息
        this.logError(error);
        
        // 上报错误
        if (this.options.reportEndpoint) {
            this.reportError(error);
        }
        
        return error;
    }
    
    // 获取错误键
    getErrorKey(error) {
        return `${error.type}:${error.message}:${error.filename || ''}:${error.lineno || ''}`;
    }
    
    // 记录错误日志
    logError(error) {
        console.group(`🚨 ${error.type.toUpperCase()} Error`);
        console.error('Message:', error.message);
        
        if (error.filename) {
            console.error('File:', error.filename);
        }
        
        if (error.lineno) {
            console.error('Line:', error.lineno);
        }
        
        if (error.stack) {
            console.error('Stack:', error.stack);
        }
        
        console.error('Timestamp:', new Date(error.timestamp).toISOString());
        console.error('URL:', error.url);
        console.groupEnd();
    }
    
    // 上报错误
    async reportError(error) {
        try {
            const response = await fetch(this.options.reportEndpoint, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(error)
            });
            
            if (!response.ok) {
                console.warn('错误上报失败:', response.status);
            }
        } catch (reportError) {
            console.warn('错误上报异常:', reportError);
        }
    }
    
    // 手动记录错误
    captureError(error, context = {}) {
        return this.recordError({
            type: 'manual',
            message: error.message || error.toString(),
            error,
            stack: error.stack,
            context
        });
    }
    
    // 获取错误统计
    getErrorStats() {
        const stats = {
            total: this.errors.length,
            byType: {},
            byTime: {},
            topErrors: []
        };
        
        // 按类型统计
        this.errors.forEach(error => {
            stats.byType[error.type] = (stats.byType[error.type] || 0) + 1;
        });
        
        // 按时间统计(最近24小时)
        const now = Date.now();
        const oneDayAgo = now - 24 * 60 * 60 * 1000;
        
        this.errors.forEach(error => {
            if (error.timestamp > oneDayAgo) {
                const hour = new Date(error.timestamp).getHours();
                stats.byTime[hour] = (stats.byTime[hour] || 0) + 1;
            }
        });
        
        // 最频繁的错误
        const sortedErrors = Array.from(this.errorCounts.entries())
            .sort((a, b) => b[1] - a[1])
            .slice(0, 10);
        
        stats.topErrors = sortedErrors.map(([key, count]) => ({ key, count }));
        
        return stats;
    }
    
    // 清除错误记录
    clearErrors() {
        this.errors = [];
        this.errorCounts.clear();
    }
    
    // 导出错误数据
    exportErrors() {
        return {
            timestamp: Date.now(),
            errors: this.errors,
            stats: this.getErrorStats()
        };
    }
}

8.5 实践练习

8.5.1 创建性能监控面板

<!DOCTYPE html>
<html>
<head>
    <title>性能监控面板</title>
    <style>
        .monitor-panel {
            position: fixed;
            top: 10px;
            right: 10px;
            width: 300px;
            background: rgba(0, 0, 0, 0.9);
            color: white;
            padding: 15px;
            border-radius: 8px;
            font-family: monospace;
            font-size: 12px;
            z-index: 10000;
        }
        
        .metric {
            margin: 5px 0;
            display: flex;
            justify-content: space-between;
        }
        
        .metric-value {
            font-weight: bold;
        }
        
        .metric-good { color: #4CAF50; }
        .metric-warning { color: #FF9800; }
        .metric-danger { color: #F44336; }
        
        .chart {
            height: 50px;
            background: #333;
            margin: 10px 0;
            position: relative;
            overflow: hidden;
        }
        
        .chart-bar {
            position: absolute;
            bottom: 0;
            width: 2px;
            background: #4CAF50;
            transition: height 0.3s ease;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>Sciter-JS 性能监控演示</h1>
        <button onclick="simulateWork()">模拟工作负载</button>
        <button onclick="simulateMemoryLeak()">模拟内存泄漏</button>
        <button onclick="simulateError()">模拟错误</button>
    </div>
    
    <div id="monitor-panel" class="monitor-panel">
        <h3>性能监控</h3>
        <div class="metric">
            <span>FPS:</span>
            <span id="fps-value" class="metric-value">--</span>
        </div>
        <div class="metric">
            <span>内存使用:</span>
            <span id="memory-value" class="metric-value">--</span>
        </div>
        <div class="metric">
            <span>DOM 节点:</span>
            <span id="dom-value" class="metric-value">--</span>
        </div>
        <div class="metric">
            <span>错误数量:</span>
            <span id="error-value" class="metric-value">0</span>
        </div>
        
        <div class="chart" id="fps-chart"></div>
        <div class="chart" id="memory-chart"></div>
    </div>

    <script>
        // 初始化监控系统
        const performanceMonitor = new PerformanceMonitor();
        const errorMonitor = new ErrorMonitor();
        const debugToolkit = new DebugToolkit();
        
        // 启用监控
        performanceMonitor.enable();
        errorMonitor.enable();
        debugToolkit.enable();
        
        // 性能监控面板
        class MonitorPanel {
            constructor() {
                this.fpsHistory = [];
                this.memoryHistory = [];
                this.maxHistory = 50;
                
                this.setupEventListeners();
                this.startUpdating();
            }
            
            setupEventListeners() {
                performanceMonitor.addObserver((type, data) => {
                    if (type === 'fps') {
                        this.updateFPS(data.value);
                    } else if (type === 'memory') {
                        this.updateMemory(data);
                    }
                });
                
                window.addEventListener('memoryLeakDetected', (event) => {
                    this.showAlert('检测到内存泄漏!', 'danger');
                });
            }
            
            updateFPS(fps) {
                const fpsElement = document.getElementById('fps-value');
                fpsElement.textContent = fps;
                
                // 设置颜色
                fpsElement.className = 'metric-value ';
                if (fps >= 55) {
                    fpsElement.classList.add('metric-good');
                } else if (fps >= 30) {
                    fpsElement.classList.add('metric-warning');
                } else {
                    fpsElement.classList.add('metric-danger');
                }
                
                // 更新图表
                this.fpsHistory.push(fps);
                if (this.fpsHistory.length > this.maxHistory) {
                    this.fpsHistory.shift();
                }
                this.updateChart('fps-chart', this.fpsHistory, 60);
            }
            
            updateMemory(memoryData) {
                const memoryElement = document.getElementById('memory-value');
                const memoryMB = (memoryData.used / 1024 / 1024).toFixed(1);
                memoryElement.textContent = `${memoryMB}MB`;
                
                // 设置颜色
                const usage = memoryData.used / memoryData.total;
                memoryElement.className = 'metric-value ';
                if (usage < 0.7) {
                    memoryElement.classList.add('metric-good');
                } else if (usage < 0.9) {
                    memoryElement.classList.add('metric-warning');
                } else {
                    memoryElement.classList.add('metric-danger');
                }
                
                // 更新图表
                this.memoryHistory.push(memoryData.used);
                if (this.memoryHistory.length > this.maxHistory) {
                    this.memoryHistory.shift();
                }
                this.updateChart('memory-chart', this.memoryHistory, memoryData.total);
            }
            
            updateChart(chartId, data, maxValue) {
                const chart = document.getElementById(chartId);
                chart.innerHTML = '';
                
                data.forEach((value, index) => {
                    const bar = document.createElement('div');
                    bar.className = 'chart-bar';
                    bar.style.left = `${(index / data.length) * 100}%`;
                    bar.style.height = `${(value / maxValue) * 100}%`;
                    chart.appendChild(bar);
                });
            }
            
            updateDOMNodes() {
                const domElement = document.getElementById('dom-value');
                const nodeCount = document.querySelectorAll('*').length;
                domElement.textContent = nodeCount;
                
                domElement.className = 'metric-value ';
                if (nodeCount < 1000) {
                    domElement.classList.add('metric-good');
                } else if (nodeCount < 5000) {
                    domElement.classList.add('metric-warning');
                } else {
                    domElement.classList.add('metric-danger');
                }
            }
            
            updateErrorCount() {
                const errorElement = document.getElementById('error-value');
                const errorCount = errorMonitor.errors.length;
                errorElement.textContent = errorCount;
                
                errorElement.className = 'metric-value ';
                if (errorCount === 0) {
                    errorElement.classList.add('metric-good');
                } else if (errorCount < 5) {
                    errorElement.classList.add('metric-warning');
                } else {
                    errorElement.classList.add('metric-danger');
                }
            }
            
            startUpdating() {
                setInterval(() => {
                    this.updateDOMNodes();
                    this.updateErrorCount();
                }, 1000);
            }
            
            showAlert(message, type) {
                const alert = document.createElement('div');
                alert.textContent = message;
                alert.style.cssText = `
                    position: fixed;
                    top: 50px;
                    right: 10px;
                    padding: 10px;
                    background: ${type === 'danger' ? '#F44336' : '#FF9800'};
                    color: white;
                    border-radius: 4px;
                    z-index: 10001;
                `;
                
                document.body.appendChild(alert);
                
                setTimeout(() => {
                    document.body.removeChild(alert);
                }, 3000);
            }
        }
        
        // 启动监控面板
        performanceMonitor.start();
        const monitorPanel = new MonitorPanel();
        
        // 模拟函数
        function simulateWork() {
            // 模拟CPU密集型工作
            const start = Date.now();
            while (Date.now() - start < 100) {
                Math.random();
            }
        }
        
        function simulateMemoryLeak() {
            // 模拟内存泄漏
            window.leakedData = window.leakedData || [];
            for (let i = 0; i < 10000; i++) {
                window.leakedData.push(new Array(1000).fill(Math.random()));
            }
        }
        
        function simulateError() {
            // 模拟错误
            throw new Error('这是一个模拟错误');
        }
    </script>
</body>
</html>

8.6 本章小结

核心概念

  1. 性能监控:建立完善的性能监控体系,实时跟踪应用性能指标
  2. 内存管理:有效管理内存使用,预防和检测内存泄漏
  3. 渲染优化:优化渲染性能,提升用户体验
  4. 调试工具:使用专业的调试工具和技巧快速定位问题

技术要点

  • 性能监控系统的设计和实现
  • 内存泄漏的检测和预防策略
  • 渲染性能优化技术
  • 调试工具的开发和使用
  • 错误监控和异常处理

最佳实践

  1. 持续监控:建立持续的性能监控机制
  2. 预防为主:采用预防性的优化策略
  3. 工具辅助:使用专业工具提升调试效率
  4. 数据驱动:基于数据进行性能优化决策

下一章预告

下一章我们将学习「打包部署与发布」,包括: - 项目构建和打包 - 部署策略和环境配置 - 版本管理和发布流程 - 生产环境监控