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 本章小结
核心概念
- 性能监控:建立完善的性能监控体系,实时跟踪应用性能指标
- 内存管理:有效管理内存使用,预防和检测内存泄漏
- 渲染优化:优化渲染性能,提升用户体验
- 调试工具:使用专业的调试工具和技巧快速定位问题
技术要点
- 性能监控系统的设计和实现
- 内存泄漏的检测和预防策略
- 渲染性能优化技术
- 调试工具的开发和使用
- 错误监控和异常处理
最佳实践
- 持续监控:建立持续的性能监控机制
- 预防为主:采用预防性的优化策略
- 工具辅助:使用专业工具提升调试效率
- 数据驱动:基于数据进行性能优化决策
下一章预告
下一章我们将学习「打包部署与发布」,包括: - 项目构建和打包 - 部署策略和环境配置 - 版本管理和发布流程 - 生产环境监控