主要包括以下几种策略:
1. 使用防抖和节流
-
防抖(Debouncing):在一段时间内只执行最后一次请求,适用于用户输入场景。
function debounce(func, delay) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => func.apply(this, args), delay); }; }
-
节流(Throttling):限制在一定时间内执行请求,适用于限制频繁的请求。
function throttle(func, limit) { let lastFunc; let lastRan; return function (...args) { const context = this; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout( function () { if (Date.now() - lastRan >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan), ); } }; }
2. 请求合并
-
请求去重:避免同一请求被重复发起,通过设置请求唯一标识来防止重复请求。
const pendingRequests = new Map(); async function fetchData(url, options) { const key = `${url}_${JSON.stringify(options)}`; if (pendingRequests.has(key)) { return pendingRequests.get(key); } const requestPromise = fetch(url, options).finally(() => { pendingRequests.delete(key); }); pendingRequests.set(key, requestPromise); return requestPromise; }
-
批量请求:将多个请求合并为一个请求,通过接口支持批量请求功能来减少请求数量。
3. 后端处理
-
负载均衡:使用负载均衡器将请求分发到多个服务器,避免单台服务器过载。
-
缓存:在后端使用缓存(如 Redis)存储重复请求的数据,减少数据库压力。
-
限流:在后端实施限流策略,控制每秒处理的请求数量,防止系统过载。
4. 异步处理
-
并发控制:限制并发请求的数量,通过实现并发队列来控制请求的并发数。
class Queue { constructor(limit) { this.queue = []; this.activeCount = 0; this.limit = limit; } add(fn) { return new Promise((resolve, reject) => { this.queue.push(() => fn().then(resolve).catch(reject)); this.processQueue(); }); } processQueue() { if (this.activeCount < this.limit && this.queue.length > 0) { const fn = this.queue.shift(); this.activeCount++; fn().finally(() => { this.activeCount--; this.processQueue(); }); } } }
5. 前端缓存
-
使用浏览器缓存:设置缓存头(如
Cache-Control
和ETag
)来缓存请求结果,减少重复请求。 -
本地存储:使用
localStorage
或sessionStorage
来缓存数据,避免重复请求。
6. 使用 Web Workers
- Web Workers:将一些计算密集型的请求处理任务放到 Web Worker 中,避免阻塞主线程,提升用户体验。