391 lines
6.8 KiB
JavaScript
391 lines
6.8 KiB
JavaScript
/**
|
|
* 性能优化工具集
|
|
* 包含防抖、节流、懒加载、缓存等功能
|
|
*/
|
|
|
|
/**
|
|
* 防抖函数
|
|
* @param {Function} func 要执行的函数
|
|
* @param {Number} wait 延迟时间(毫秒)
|
|
* @param {Boolean} immediate 是否立即执行
|
|
*/
|
|
function debounce(func, wait = 300, immediate = false) {
|
|
let timeout
|
|
|
|
return function executedFunction(...args) {
|
|
const context = this
|
|
|
|
const later = function() {
|
|
timeout = null
|
|
if (!immediate) func.apply(context, args)
|
|
}
|
|
|
|
const callNow = immediate && !timeout
|
|
|
|
clearTimeout(timeout)
|
|
timeout = setTimeout(later, wait)
|
|
|
|
if (callNow) func.apply(context, args)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 节流函数
|
|
* @param {Function} func 要执行的函数
|
|
* @param {Number} limit 时间限制(毫秒)
|
|
*/
|
|
function throttle(func, limit = 300) {
|
|
let inThrottle
|
|
|
|
return function(...args) {
|
|
const context = this
|
|
|
|
if (!inThrottle) {
|
|
func.apply(context, args)
|
|
inThrottle = true
|
|
setTimeout(() => inThrottle = false, limit)
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 缓存管理器
|
|
*/
|
|
class CacheManager {
|
|
constructor() {
|
|
this.cache = new Map()
|
|
this.maxSize = 50 // 最大缓存数量
|
|
this.ttl = 5 * 60 * 1000 // 默认5分钟过期
|
|
}
|
|
|
|
/**
|
|
* 设置缓存
|
|
*/
|
|
set(key, value, ttl = this.ttl) {
|
|
if (this.cache.size >= this.maxSize) {
|
|
// 删除最早的缓存
|
|
const firstKey = this.cache.keys().next().value
|
|
this.cache.delete(firstKey)
|
|
}
|
|
|
|
this.cache.set(key, {
|
|
value,
|
|
expires: Date.now() + ttl
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 获取缓存
|
|
*/
|
|
get(key) {
|
|
const item = this.cache.get(key)
|
|
|
|
if (!item) {
|
|
return null
|
|
}
|
|
|
|
if (Date.now() > item.expires) {
|
|
this.cache.delete(key)
|
|
return null
|
|
}
|
|
|
|
return item.value
|
|
}
|
|
|
|
/**
|
|
* 删除缓存
|
|
*/
|
|
delete(key) {
|
|
return this.cache.delete(key)
|
|
}
|
|
|
|
/**
|
|
* 清空缓存
|
|
*/
|
|
clear() {
|
|
this.cache.clear()
|
|
}
|
|
|
|
/**
|
|
* 获取缓存大小
|
|
*/
|
|
size() {
|
|
return this.cache.size
|
|
}
|
|
|
|
/**
|
|
* 清理过期缓存
|
|
*/
|
|
cleanup() {
|
|
const now = Date.now()
|
|
for (const [key, item] of this.cache.entries()) {
|
|
if (now > item.expires) {
|
|
this.cache.delete(key)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 图片懒加载管理器
|
|
*/
|
|
class LazyLoadManager {
|
|
constructor() {
|
|
this.observer = null
|
|
this.images = []
|
|
}
|
|
|
|
/**
|
|
* 初始化懒加载
|
|
*/
|
|
init(selector = '.lazy-image') {
|
|
if (!wx.createIntersectionObserver) {
|
|
console.warn('当前环境不支持IntersectionObserver')
|
|
return
|
|
}
|
|
|
|
this.observer = wx.createIntersectionObserver()
|
|
|
|
this.observer.relativeToViewport({ bottom: 100 })
|
|
|
|
this.observer.observe(selector, (res) => {
|
|
if (res.intersectionRatio > 0) {
|
|
this.loadImage(res.id)
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 加载图片
|
|
*/
|
|
loadImage(id) {
|
|
const image = this.images.find(img => img.id === id)
|
|
if (image && !image.loaded) {
|
|
image.loaded = true
|
|
// 触发图片加载
|
|
if (image.callback) {
|
|
image.callback()
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 添加图片
|
|
*/
|
|
addImage(id, callback) {
|
|
this.images.push({ id, loaded: false, callback })
|
|
}
|
|
|
|
/**
|
|
* 销毁
|
|
*/
|
|
destroy() {
|
|
if (this.observer) {
|
|
this.observer.disconnect()
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 分页加载管理器
|
|
*/
|
|
class PaginationManager {
|
|
constructor(config = {}) {
|
|
this.pageSize = config.pageSize || 20
|
|
this.currentPage = 1
|
|
this.totalPages = 0
|
|
this.totalCount = 0
|
|
this.hasMore = true
|
|
this.loading = false
|
|
this.data = []
|
|
}
|
|
|
|
/**
|
|
* 加载下一页
|
|
*/
|
|
async loadMore(fetchFunction) {
|
|
if (this.loading || !this.hasMore) {
|
|
return null
|
|
}
|
|
|
|
this.loading = true
|
|
|
|
try {
|
|
const result = await fetchFunction(this.currentPage, this.pageSize)
|
|
|
|
this.data = [...this.data, ...result.data]
|
|
this.totalCount = result.total
|
|
this.totalPages = Math.ceil(result.total / this.pageSize)
|
|
this.hasMore = this.currentPage < this.totalPages
|
|
this.currentPage++
|
|
|
|
return result
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 重置
|
|
*/
|
|
reset() {
|
|
this.currentPage = 1
|
|
this.totalPages = 0
|
|
this.totalCount = 0
|
|
this.hasMore = true
|
|
this.loading = false
|
|
this.data = []
|
|
}
|
|
|
|
/**
|
|
* 获取状态
|
|
*/
|
|
getState() {
|
|
return {
|
|
currentPage: this.currentPage,
|
|
totalPages: this.totalPages,
|
|
totalCount: this.totalCount,
|
|
hasMore: this.hasMore,
|
|
loading: this.loading,
|
|
dataLength: this.data.length
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 性能监控器
|
|
*/
|
|
class PerformanceMonitor {
|
|
constructor() {
|
|
this.metrics = []
|
|
}
|
|
|
|
/**
|
|
* 开始监控
|
|
*/
|
|
start(name) {
|
|
return {
|
|
name,
|
|
startTime: Date.now(),
|
|
end: () => this.end(name, Date.now())
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 结束监控
|
|
*/
|
|
end(name, startTime) {
|
|
const duration = Date.now() - startTime
|
|
|
|
this.metrics.push({
|
|
name,
|
|
duration,
|
|
timestamp: Date.now()
|
|
})
|
|
|
|
// 性能警告
|
|
if (duration > 1000) {
|
|
console.warn(`[性能警告] ${name} 耗时 ${duration}ms`)
|
|
}
|
|
|
|
return duration
|
|
}
|
|
|
|
/**
|
|
* 获取指标
|
|
*/
|
|
getMetrics(name) {
|
|
if (name) {
|
|
return this.metrics.filter(m => m.name === name)
|
|
}
|
|
return this.metrics
|
|
}
|
|
|
|
/**
|
|
* 获取平均时间
|
|
*/
|
|
getAverage(name) {
|
|
const metrics = this.getMetrics(name)
|
|
if (metrics.length === 0) return 0
|
|
|
|
const total = metrics.reduce((sum, m) => sum + m.duration, 0)
|
|
return total / metrics.length
|
|
}
|
|
|
|
/**
|
|
* 清空指标
|
|
*/
|
|
clear() {
|
|
this.metrics = []
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 数据预加载管理器
|
|
*/
|
|
class PreloadManager {
|
|
constructor() {
|
|
this.preloadQueue = []
|
|
this.maxConcurrent = 3
|
|
this.running = 0
|
|
}
|
|
|
|
/**
|
|
* 添加预加载任务
|
|
*/
|
|
add(task, priority = 0) {
|
|
this.preloadQueue.push({ task, priority })
|
|
this.preloadQueue.sort((a, b) => b.priority - a.priority)
|
|
this.process()
|
|
}
|
|
|
|
/**
|
|
* 处理队列
|
|
*/
|
|
async process() {
|
|
while (this.running < this.maxConcurrent && this.preloadQueue.length > 0) {
|
|
const { task } = this.preloadQueue.shift()
|
|
this.running++
|
|
|
|
try {
|
|
await task()
|
|
} catch (e) {
|
|
console.error('预加载失败:', e)
|
|
} finally {
|
|
this.running--
|
|
this.process()
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 清空队列
|
|
*/
|
|
clear() {
|
|
this.preloadQueue = []
|
|
}
|
|
}
|
|
|
|
// 创建全局实例
|
|
const cacheManager = new CacheManager()
|
|
const performanceMonitor = new PerformanceMonitor()
|
|
const preloadManager = new PreloadManager()
|
|
|
|
// 定期清理过期缓存
|
|
setInterval(() => {
|
|
cacheManager.cleanup()
|
|
}, 60 * 1000) // 每分钟清理一次
|
|
|
|
module.exports = {
|
|
debounce,
|
|
throttle,
|
|
CacheManager,
|
|
cacheManager,
|
|
LazyLoadManager,
|
|
PaginationManager,
|
|
PerformanceMonitor,
|
|
performanceMonitor,
|
|
PreloadManager,
|
|
preloadManager
|
|
}
|