主题
缓存与重复请求优化
在大型前端项目中,频繁请求相同接口可能导致性能下降和不必要的网络流量。 Axios 提供了多种方式结合缓存策略与请求去重,优化前端性能。
一、为什么需要缓存与请求去重
- 减少相同接口的重复请求,降低服务器压力。
- 提升用户体验,尤其是在慢网或移动端。
- 避免多次重复请求导致的数据冲突或界面闪烁。
二、浏览器缓存机制
利用 HTTP 缓存头:
Cache-Control:控制缓存策略,如max-age、no-cache。ETag:资源标识符变化时更新缓存。Last-Modified:资源修改时间。
Axios 可结合
If-None-Match/If-Modified-Since头实现条件请求:
js
axios.get('/api/data', {
headers: {
'If-None-Match': cachedETag
}
});三、内存缓存(前端请求去重)
使用简单对象或 Map 缓存请求结果:
js
const cache = new Map();
async function fetchWithCache(url) {
if (cache.has(url)) {
return cache.get(url);
}
const response = await axios.get(url);
cache.set(url, response);
return response;
}四、结合拦截器实现全局缓存
js
const cacheStore = new Map();
axios.interceptors.request.use(config => {
const key = config.url + JSON.stringify(config.params || {});
if (cacheStore.has(key)) {
config.adapter = () => {
return Promise.resolve(cacheStore.get(key));
};
}
return config;
});
axios.interceptors.response.use(response => {
const key = response.config.url + JSON.stringify(response.config.params || {});
cacheStore.set(key, response);
return response;
});五、防止重复请求
- 对同一 URL 和参数的请求,在前一个未完成时阻止再次发送。
js
const pending = new Map();
function requestWithDedup(config) {
const key = config.url + JSON.stringify(config.params || {});
if (pending.has(key)) {
return pending.get(key);
}
const request = axios(config).finally(() => pending.delete(key));
pending.set(key, request);
return request;
}六、缓存过期与更新策略
- 可设置时间戳过期:
js
const cache = new Map();
function fetchWithExpiry(url, ttl = 5000) {
const now = Date.now();
const cached = cache.get(url);
if (cached && (now - cached.time < ttl)) {
return Promise.resolve(cached.response);
}
return axios.get(url).then(res => {
cache.set(url, { response: res, time: now });
return res;
});
}- 支持手动清理或基于版本号更新缓存。
七、小结
优化缓存和防止重复请求,可以显著提升前端性能与用户体验。 最佳实践:
- 静态数据优先使用浏览器缓存。
- 动态数据结合内存缓存和请求去重。
- 使用拦截器统一管理缓存逻辑。
- 对幂等请求安全重试,对非幂等请求谨慎。