miniprogramme/utils/performance-optimizer.js

326 lines
7.9 KiB
JavaScript
Raw Normal View History

2025-09-12 16:08:17 +08:00
// 性能优化工具 - 提升小程序性能和用户体验
class PerformanceOptimizer {
constructor() {
this.imageCache = new Map();
this.requestCache = new Map();
this.lazyLoadObserver = null;
this.performanceMetrics = {
pageLoadTimes: [],
apiResponseTimes: [],
imageLoadTimes: []
};
}
// 🔥 ===== 图片优化 =====
// 图片懒加载
initLazyLoad() {
// 创建懒加载观察器
this.lazyLoadObserver = wx.createIntersectionObserver();
this.lazyLoadObserver.observe('.lazy-image', (res) => {
if (res.intersectionRatio > 0) {
// 图片进入视口,开始加载
const dataset = res.dataset;
if (dataset && dataset.src) {
this.loadImage(dataset.src, res.id);
}
}
});
}
// 优化图片加载
async loadImage(src, elementId) {
try {
const startTime = Date.now();
// 检查缓存
if (this.imageCache.has(src)) {
const cachedImage = this.imageCache.get(src);
this.updateImageElement(elementId, cachedImage);
return cachedImage;
}
// 预加载图片
const imageInfo = await this.preloadImage(src);
// 缓存图片信息
this.imageCache.set(src, imageInfo);
// 更新元素
this.updateImageElement(elementId, imageInfo);
// 记录性能指标
const loadTime = Date.now() - startTime;
this.recordImageLoadTime(loadTime);
return imageInfo;
} catch (error) {
console.error('图片加载失败:', error);
// 使用默认图片
this.updateImageElement(elementId, { path: '/assets/images/placeholder.png' });
}
}
// 预加载图片
preloadImage(src) {
return new Promise((resolve, reject) => {
wx.getImageInfo({
src: src,
success: resolve,
fail: reject
});
});
}
// 更新图片元素
updateImageElement(elementId, imageInfo) {
// 这里需要页面配合实现具体的更新逻辑
console.log('更新图片元素:', elementId, imageInfo);
}
// 🔥 ===== 请求优化 =====
// 请求缓存
async cacheRequest(key, requestFn, ttl = 300000) { // 默认5分钟缓存
const now = Date.now();
// 检查缓存
if (this.requestCache.has(key)) {
const cached = this.requestCache.get(key);
if (now - cached.timestamp < ttl) {
console.log('使用缓存数据:', key);
return cached.data;
}
}
try {
const startTime = Date.now();
const data = await requestFn();
const responseTime = Date.now() - startTime;
// 缓存数据
this.requestCache.set(key, {
data: data,
timestamp: now
});
// 记录性能指标
this.recordApiResponseTime(responseTime);
return data;
} catch (error) {
console.error('请求失败:', error);
throw error;
}
}
// 清除过期缓存
clearExpiredCache() {
const now = Date.now();
const maxAge = 600000; // 10分钟
for (const [key, value] of this.requestCache.entries()) {
if (now - value.timestamp > maxAge) {
this.requestCache.delete(key);
}
}
}
// 🔥 ===== 内存优化 =====
// 清理内存
cleanupMemory() {
// 清理图片缓存
if (this.imageCache.size > 50) {
const entries = Array.from(this.imageCache.entries());
const toDelete = entries.slice(0, entries.length - 30);
toDelete.forEach(([key]) => {
this.imageCache.delete(key);
});
}
// 清理请求缓存
this.clearExpiredCache();
// 触发垃圾回收(如果可用)
if (wx.triggerGC) {
wx.triggerGC();
}
}
// 监控内存使用
monitorMemory() {
if (wx.getPerformance) {
const performance = wx.getPerformance();
const memory = performance.memory;
if (memory) {
console.log('内存使用情况:', {
used: this.formatBytes(memory.usedJSHeapSize),
total: this.formatBytes(memory.totalJSHeapSize),
limit: this.formatBytes(memory.jsHeapSizeLimit)
});
// 如果内存使用超过80%,触发清理
if (memory.usedJSHeapSize / memory.jsHeapSizeLimit > 0.8) {
console.warn('内存使用过高,开始清理');
this.cleanupMemory();
}
}
}
}
// 🔥 ===== 性能监控 =====
// 记录页面加载时间
recordPageLoadTime(loadTime) {
this.performanceMetrics.pageLoadTimes.push(loadTime);
// 只保留最近100条记录
if (this.performanceMetrics.pageLoadTimes.length > 100) {
this.performanceMetrics.pageLoadTimes.shift();
}
}
// 记录API响应时间
recordApiResponseTime(responseTime) {
this.performanceMetrics.apiResponseTimes.push(responseTime);
if (this.performanceMetrics.apiResponseTimes.length > 100) {
this.performanceMetrics.apiResponseTimes.shift();
}
}
// 记录图片加载时间
recordImageLoadTime(loadTime) {
this.performanceMetrics.imageLoadTimes.push(loadTime);
if (this.performanceMetrics.imageLoadTimes.length > 100) {
this.performanceMetrics.imageLoadTimes.shift();
}
}
// 获取性能报告
getPerformanceReport() {
const report = {
pageLoad: this.calculateStats(this.performanceMetrics.pageLoadTimes),
apiResponse: this.calculateStats(this.performanceMetrics.apiResponseTimes),
imageLoad: this.calculateStats(this.performanceMetrics.imageLoadTimes),
cacheStats: {
imageCache: this.imageCache.size,
requestCache: this.requestCache.size
}
};
console.log('性能报告:', report);
return report;
}
// 计算统计数据
calculateStats(times) {
if (times.length === 0) {
return { avg: 0, min: 0, max: 0, count: 0 };
}
const sum = times.reduce((a, b) => a + b, 0);
const avg = sum / times.length;
const min = Math.min(...times);
const max = Math.max(...times);
return {
avg: Math.round(avg),
min: min,
max: max,
count: times.length
};
}
// 🔥 ===== 工具方法 =====
// 格式化字节数
formatBytes(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// 防抖函数
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 节流函数
throttle(func, limit) {
let inThrottle;
return function executedFunction(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 🔥 ===== 初始化和清理 =====
// 初始化性能优化
init() {
console.log('初始化性能优化器');
// 初始化懒加载
this.initLazyLoad();
// 定期清理内存
setInterval(() => {
this.cleanupMemory();
}, 300000); // 5分钟清理一次
// 定期监控内存
setInterval(() => {
this.monitorMemory();
}, 60000); // 1分钟监控一次
}
// 销毁优化器
destroy() {
console.log('销毁性能优化器');
// 清理懒加载观察器
if (this.lazyLoadObserver) {
this.lazyLoadObserver.disconnect();
this.lazyLoadObserver = null;
}
// 清理缓存
this.imageCache.clear();
this.requestCache.clear();
// 清理性能指标
this.performanceMetrics = {
pageLoadTimes: [],
apiResponseTimes: [],
imageLoadTimes: []
};
}
}
// 创建全局单例
const performanceOptimizer = new PerformanceOptimizer();
module.exports = performanceOptimizer;