以下是前端数据缓存的完整解决方案,涵盖策略设计、技术实现和性能优化:
一、缓存策略分层设计
二、核心场景实现方案
1. 高频请求数据缓存(内存缓存)
// 使用Map实现LRU缓存
class MemoryCache {constructor(maxSize = 100) {this.cache = new Map()this.maxSize = maxSize}get(key) {const item = this.cache.get(key)if (item) {// 更新访问顺序this.cache.delete(key)this.cache.set(key, item)}return item?.value}set(key, value, ttl = 60_000) {if (this.cache.size >= this.maxSize) {// 删除最久未使用的const oldestKey = this.cache.keys().next().valuethis.cache.delete(oldestKey)}this.cache.set(key, {value,expire: Date.now() + ttl})}clearExpired() {const now = Date.now()for (const [key, { expire }] of this.cache) {if (now > expire) this.cache.delete(key)}}
}// 使用示例
const apiCache = new MemoryCache(50)
2. 持久化重要数据(LocalStorage + 版本控制)
const CACHE_VERSION = 'v1.3'function getCache(key) {try {const data = localStorage.getItem(`${CACHE_VERSION}_${key}`)return data ? JSON.parse(data) : null} catch (error) {console.error('缓存读取失败', error)return null}
}function setCache(key, value, ttl = 3600_000) {const data = {value,expire: Date.now() + ttl,timestamp: Date.now()}localStorage.setItem(`${CACHE_VERSION}_${key}`,JSON.stringify(data))
}// 定时清理过期缓存
setInterval(() => {Object.keys(localStorage).forEach(key => {if (key.startsWith(CACHE_VERSION)) {const data = JSON.parse(localStorage.getItem(key))if (data?.expire < Date.now()) {localStorage.removeItem(key)}}})
}, 60_000)
3. 接口请求缓存策略
const apiCache = new Map()async function cachedFetch(url, options = {}) {const cacheKey = JSON.stringify({ url, options })// 命中缓存if (apiCache.has(cacheKey)) {const { expire, data } = apiCache.get(cacheKey)if (Date.now() < expire) return data.clone()}// 发起真实请求const response = await fetch(url, options)const cloneRes = response.clone()// 缓存新数据apiCache.set(cacheKey, {data: cloneRes,expire: Date.now() + (options.ttl || 300_000)})return response
}
三、高级缓存模式
1. 缓存分层策略
async function getData(key) {// 第一层:内存缓存let data = memoryCache.get(key)if (data) return data// 第二层:本地存储data = getLocalCache(key)if (data) {memoryCache.set(key, data)return data}// 第三层:网络请求data = await fetchData(key)memoryCache.set(key, data)setLocalCache(key, data)return data
}
2. 缓存更新策略
// Stale-While-Revalidate 模式
function swrFetch(url, ttl = 300_000) {const cached = getCache(url)// 立即返回过期数据,后台更新if (cached) {if (Date.now() < cached.expire) {return Promise.resolve(cached.value)} else {fetch(url).then(updateCache).catch(console.error)return cached.value}}// 无缓存则正常请求return fetch(url).then(updateCache)
}
四、性能优化方案
1. Web Worker 缓存处理
// 主线程
const worker = new Worker('cache-worker.js')worker.postMessage({type: 'SET_CACHE',key: 'userData',value: userData
})// Worker线程处理
self.onmessage = (e) => {if (e.data.type === 'SET_CACHE') {IndexedDB.set(e.data.key, e.data.value)}
}
2. 缓存压缩策略
function compressData(data) {const str = JSON.stringify(data)const compressed = LZString.compress(str)return compressed
}function decompressData(compressed) {const str = LZString.decompress(compressed)return JSON.parse(str)
}
五、缓存监控与调试
1. 缓存命中率统计
const cacheStats = {total: 0,hits: 0,misses: 0
}function trackCacheAccess(isHit) {cacheStats.total++isHit ? cacheStats.hits++ : cacheStats.misses++if (cacheStats.total % 100 === 0) {console.log(`缓存命中率: ${(cacheStats.hits/cacheStats.total*100).toFixed(1)}%`)}
}
2. Chrome DevTools 调试
// 暴露缓存接口到全局
window.__debugCache = {clear: () => {memoryCache.clear()localStorage.clear()},stats: () => cacheStats
}
六、最佳实践建议
-
缓存Key设计原则
// 好的Key设计示例 const getCacheKey = (apiPath, params) => {const sortedParams = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&')return `api_${apiPath}?${sortedParams}` }
-
敏感数据处理
// 加密敏感缓存 import CryptoJS from 'crypto-js'function secureSet(key, value) {const encrypted = CryptoJS.AES.encrypt(JSON.stringify(value),process.env.CACHE_SECRET).toString()localStorage.setItem(key, encrypted) }
-
缓存容量控制
// IndexedDB容量监测 navigator.storage.estimate().then(estimate => {console.log(`已使用: ${estimate.usage/1024/1024}MB`)console.log(`限额: ${estimate.quota/1024/1024}MB`) })
七、不同场景推荐方案
场景 | 推荐方案 | 优势 | 注意事项 |
---|---|---|---|
高频更新数据 | 内存缓存 | 访问速度快 | 需设置合理TTL |
大型数据集 | IndexedDB | 支持结构化存储 | 需处理版本迁移 |
离线优先 | Service Worker | 网络不可用仍可访问 | 需处理缓存更新 |
敏感信息 | 加密存储 | 数据安全 | 加解密性能损耗 |
通过合理使用这些缓存策略,可以实现:
- 首屏加载速度提升 30%-70% ⚡
- 接口请求量减少 40%+ 📉
- 离线场景正常使用 📴
- 流量消耗显著降低 🌐
建议结合业务需求选择缓存层级,并定期通过 window.performance.memory
监控内存使用情况,避免过度缓存导致内存泄漏。