离线缓存策略设计
离线缓存策略设计
离线缓存是提升应用性能的关键手段之一,尤其在网络不稳定或弱网环境下,合理的缓存策略能显著改善用户体验。通过预加载、动态更新和智能过期机制,可以有效减少网络请求次数,降低服务器压力,同时保证数据的时效性。
缓存类型与选择
根据存储介质和生命周期,前端缓存主要分为以下几种:
- Memory Cache:内存缓存,读取速度最快但生命周期短,页面关闭即失效
- Session Storage:会话级存储,同一标签页内有效
- Local Storage:持久化存储,需手动清除
- IndexedDB:结构化数据存储,适合大量数据
- Service Worker Cache:网络请求拦截缓存,PWA核心技术
// 缓存类型使用示例
const cacheData = {
// 内存缓存(临时数据)
memoryCache: new Map(),
// 会话存储(表单状态)
saveSessionData(key, value) {
sessionStorage.setItem(key, JSON.stringify(value));
},
// 本地存储(用户偏好)
saveLocalData(key, value) {
localStorage.setItem(key, JSON.stringify(value));
}
};
缓存更新策略
定时过期策略
设置固定的缓存有效期,适合变化周期固定的数据:
function getWithExpiry(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
const item = JSON.parse(itemStr);
if (Date.now() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
}
function setWithExpiry(key, value, ttl) {
const item = {
value: value,
expiry: Date.now() + ttl
};
localStorage.setItem(key, JSON.stringify(item));
}
版本号控制
通过版本标识强制更新缓存:
const CACHE_VERSION = 'v1.2';
const getCacheKey = (key) => `${CACHE_VERSION}_${key}`;
function fetchWithCache(url) {
const cacheKey = getCacheKey(url);
const cached = localStorage.getItem(cacheKey);
if (cached) return Promise.resolve(JSON.parse(cached));
return fetch(url)
.then(res => res.json())
.then(data => {
localStorage.setItem(cacheKey, JSON.stringify(data));
return data;
});
}
混合缓存策略设计
分层缓存方案
构建多级缓存体系提高命中率:
class HybridCache {
constructor() {
this.memoryCache = new Map();
this.SWSupported = 'serviceWorker' in navigator;
}
async get(url) {
// 第一层:内存缓存
if (this.memoryCache.has(url)) {
return this.memoryCache.get(url);
}
// 第二层:Service Worker缓存
if (this.SWSupported) {
const cached = await caches.match(url);
if (cached) {
const data = await cached.json();
this.memoryCache.set(url, data); // 回填内存缓存
return data;
}
}
// 第三层:网络请求
const freshData = await fetch(url).then(r => r.json());
this.memoryCache.set(url, freshData);
return freshData;
}
}
智能预加载策略
结合用户行为预测进行缓存预热:
// 基于路由的预加载
const preloadMap = {
'/home': ['/api/news', '/api/announcements'],
'/products': ['/api/categories', '/api/hot-products']
};
router.beforeEach((to, from, next) => {
const preloadUrls = preloadMap[to.path];
if (preloadUrls) {
preloadUrls.forEach(url => {
fetch(url, { cache: 'force-cache' })
.then(res => res.json())
.then(data => cacheStore.set(url, data));
});
}
next();
});
缓存清理机制
基于LRU的清理
实现最近最少使用淘汰算法:
class LRUCache {
constructor(maxSize = 20) {
this.cache = new Map();
this.maxSize = maxSize;
}
get(key) {
if (!this.cache.has(key)) return null;
const value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value);
return value;
}
set(key, value) {
if (this.cache.has(key)) {
this.cache.delete(key);
} else if (this.cache.size >= this.maxSize) {
// 删除最久未使用的条目
const oldestKey = this.cache.keys().next().value;
this.cache.delete(oldestKey);
}
this.cache.set(key, value);
}
}
存储空间监控
动态调整缓存策略基于可用空间:
function getStorageQuota() {
return new Promise((resolve) => {
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate().then(estimate => {
const used = estimate.usage;
const quota = estimate.quota;
resolve({ used, quota, ratio: used / quota });
});
} else {
// 兼容方案
try {
localStorage.setItem('test', 'x');
localStorage.removeItem('test');
resolve({ status: 'supported' });
} catch (e) {
resolve({ status: 'full' });
}
}
});
}
异常处理与降级方案
缓存系统需要完善的错误处理机制:
async function robustCacheFetch(url, fallbackUrl) {
try {
// 优先尝试从缓存获取
const cachedResponse = await caches.match(url);
if (cachedResponse) return cachedResponse.json();
// 网络请求
const networkResponse = await fetch(url);
// 缓存新响应
const cache = await caches.open('dynamic-v1');
await cache.put(url, networkResponse.clone());
return networkResponse.json();
} catch (error) {
console.error('Fetch failed:', error);
// 降级方案1:尝试备用URL
if (fallbackUrl) {
return fetch(fallbackUrl).then(r => r.json());
}
// 降级方案2:返回过期的缓存
const staleResponse = await caches.match(url);
if (staleResponse) {
return staleResponse.json();
}
// 最终降级:返回预设默认值
return { status: 'offline', data: [] };
}
}
性能监控与调优
实现缓存命中率统计帮助优化策略:
const cacheStats = {
hits: 0,
misses: 0,
get hitRate() {
return this.hits / (this.hits + this.misses) || 0;
}
};
function instrumentedFetch(url) {
return fetch(url).then(response => {
// 记录原始响应时间
const timing = performance.now();
return {
response,
timing,
markHit() {
cacheStats.hits++;
},
markMiss() {
cacheStats.misses++;
}
};
});
}
// 使用示例
async function getData(url) {
const { response, timing, markHit, markMiss } = await instrumentedFetch(url);
if (fromCache(response)) {
markHit();
} else {
markMiss();
}
return response;
}
浏览器兼容性处理
针对不同浏览器实现统一缓存接口:
const cacheWrapper = {
set(key, value) {
try {
if (window.localStorage) {
localStorage.setItem(key, JSON.stringify(value));
return true;
}
} catch (e) {
console.warn('LocalStorage full, falling back to memory');
}
// 降级到内存缓存
if (!this.memoryCache) this.memoryCache = {};
this.memoryCache[key] = value;
return false;
},
get(key) {
// 优先检查内存缓存
if (this.memoryCache && key in this.memoryCache) {
return this.memoryCache[key];
}
try {
if (window.localStorage) {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : null;
}
} catch (e) {
console.error('LocalStorage access error');
}
return null;
}
};
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:智能资源加载策略
下一篇:图片优化格式选择与压缩