Files
database_render/web/static/js/performance-monitor.js
2025-08-07 20:03:53 +08:00

233 lines
6.1 KiB
JavaScript

/**
* 性能监控器 - 监控和优化前端性能
*/
class PerformanceMonitor {
constructor() {
this.metrics = new Map();
this.observers = new Set();
this.isEnabled = true;
this.threshold = {
renderTime: 1000, // 渲染时间阈值
loadTime: 2000, // 加载时间阈值
memoryUsage: 100 * 1024 * 1024 // 内存使用阈值
};
this.init();
}
/**
* 初始化性能监控
*/
init() {
if (typeof window !== 'undefined' && window.performance) {
this.setupPerformanceObserver();
this.setupMemoryMonitor();
}
}
/**
* 设置性能观察器
*/
setupPerformanceObserver() {
if ('PerformanceObserver' in window) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
this.recordMetric(entry.name, {
duration: entry.duration,
startTime: entry.startTime,
type: entry.entryType
});
}
});
observer.observe({ entryTypes: ['measure', 'navigation', 'resource'] });
}
}
/**
* 设置内存监控
*/
setupMemoryMonitor() {
if ('memory' in performance) {
setInterval(() => {
const memory = performance.memory;
this.recordMetric('memory', {
used: memory.usedJSHeapSize,
total: memory.totalJSHeapSize,
limit: memory.jsHeapSizeLimit,
timestamp: Date.now()
});
// 检查内存使用是否超过阈值
if (memory.usedJSHeapSize > this.threshold.memoryUsage) {
this.triggerAlert('high_memory_usage', {
used: memory.usedJSHeapSize,
limit: this.threshold.memoryUsage
});
}
}, 10000); // 每10秒检查一次
}
}
/**
* 记录性能指标
* @param {string} name - 指标名称
* @param {Object} data - 指标数据
*/
recordMetric(name, data) {
if (!this.isEnabled) return;
if (!this.metrics.has(name)) {
this.metrics.set(name, []);
}
const records = this.metrics.get(name);
records.push({
...data,
timestamp: Date.now()
});
// 限制记录数量
if (records.length > 100) {
records.shift();
}
// 触发观察者通知
this.notifyObservers(name, data);
}
/**
* 开始性能计时
* @param {string} name - 计时器名称
*/
startTimer(name) {
if (typeof window !== 'undefined' && window.performance) {
performance.mark(`${name}_start`);
}
}
/**
* 结束性能计时
* @param {string} name - 计时器名称
*/
endTimer(name) {
if (typeof window !== 'undefined' && window.performance) {
performance.mark(`${name}_end`);
performance.measure(name, `${name}_start`, `${name}_end`);
}
}
/**
* 获取性能指标
* @param {string} name - 指标名称
*/
getMetric(name) {
return this.metrics.get(name) || [];
}
/**
* 获取平均渲染时间
*/
getAverageRenderTime() {
const renders = this.getMetric('template-render');
if (renders.length === 0) return 0;
const total = renders.reduce((sum, r) => sum + r.duration, 0);
return total / renders.length;
}
/**
* 添加性能观察者
* @param {Function} callback - 回调函数
*/
addObserver(callback) {
this.observers.add(callback);
}
/**
* 移除性能观察者
* @param {Function} callback - 回调函数
*/
removeObserver(callback) {
this.observers.delete(callback);
}
/**
* 通知观察者
* @param {string} name - 指标名称
* @param {Object} data - 指标数据
*/
notifyObservers(name, data) {
this.observers.forEach(callback => {
try {
callback(name, data);
} catch (error) {
console.error('Performance observer error:', error);
}
});
}
/**
* 触发性能警报
* @param {string} type - 警报类型
* @param {Object} data - 警报数据
*/
triggerAlert(type, data) {
console.warn(`Performance Alert: ${type}`, data);
// 可以在这里集成错误报告服务
if (window.console && window.console.warn) {
console.warn(`[Performance] ${type}:`, data);
}
}
/**
* 获取性能报告
*/
getReport() {
const report = {
timestamp: Date.now(),
metrics: {},
summary: {
totalRequests: 0,
averageRenderTime: this.getAverageRenderTime(),
cacheHitRate: 0
}
};
// 汇总指标
for (const [name, records] of this.metrics) {
report.metrics[name] = {
count: records.length,
average: records.reduce((sum, r) => sum + (r.duration || 0), 0) / records.length,
min: Math.min(...records.map(r => r.duration || 0)),
max: Math.max(...records.map(r => r.duration || 0)),
last: records[records.length - 1]
};
}
return report;
}
/**
* 清空性能数据
*/
clear() {
this.metrics.clear();
this.observers.clear();
}
/**
* 启用/禁用性能监控
* @param {boolean} enabled - 是否启用
*/
setEnabled(enabled) {
this.isEnabled = enabled;
}
}
// 全局性能监控器实例
window.performanceMonitor = new PerformanceMonitor();
// 集成到模板引擎和API客户端中
// 在template-engine.js和api-client.js中使用performanceMonitor.startTimer/endTimer