233 lines
6.1 KiB
JavaScript
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
|