feat: update auto render
This commit is contained in:
233
web/static/js/performance-monitor.js
Normal file
233
web/static/js/performance-monitor.js
Normal file
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* 性能监控器 - 监控和优化前端性能
|
||||
*/
|
||||
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
|
||||
Reference in New Issue
Block a user