如何避免频繁调用API以减轻服务端压力,React场景下的优化方案
避免频繁调用API的可行优化方案
1. 优先合并接口请求
你当前代码中4个请求携带的参数完全一致,仅接口路径不同,可以和后端协商开发一个聚合接口,一次请求返回家长权限、学生信息、教师信息、用户资料4份数据,直接将请求量从4次降到1次,是降低服务端压力最有效的方案。
2. 添加请求状态锁,避免重复请求
如果组件存在重复挂载、逻辑重复触发的场景,可以增加请求状态标记,请求未完成时不再触发新的同类型请求,避免无效重复调用。
3. 增加本地缓存逻辑
用户权限、资料类数据一般不会频繁变更,请求成功后将数据写入本地存储(如AsyncStorage)或全局状态管理库,下次需要使用时优先读取缓存,缓存有效则无需发起新请求,可根据业务场景设置缓存过期时间(如12小时、24小时),到期后再重新请求刷新数据。
4. 复用请求逻辑,统一管控调用
你当前4个请求的处理逻辑高度重合,可以封装为通用请求函数,避免冗余代码的同时也方便统一做防抖、节流、错误处理等逻辑管控。如果确实需要保留多个独立请求,可使用Promise.all统一管理并行请求,方便统一处理成功/失败逻辑。
优化后的代码示例:
// 通用请求封装 const commonFetch = async (urlSuffix, UserId, _token) => { try { const res = await fetch(`${config.API_URL}${urlSuffix}${UserId}`, { method: 'GET', headers: { 'Authorization': `Bearer ${_token}`, 'Content-Type': 'application/json', } }) const data = await res.json() if (res.status === 200 && data?.length > 0) { return data[0].udf_Users_IsHaveApplicationAccess } console.log('请求返回异常') return null } catch (e) { console.log('请求错误', e) return null } } // 业务逻辑优化 const isFetchingRef = useRef(false) useEffect(() => { // 已有请求在进行中,直接跳过避免重复调用 if (isFetchingRef.current) return isFetchingRef.current = true const task = InteractionManager.runAfterInteractions(async () => { // 优先读取本地缓存 const cachedParent = await AsyncStorage.getItem('@cachedParent') const cachedStudent = await AsyncStorage.getItem('@cachedStudent') const cachedTeacher = await AsyncStorage.getItem('@cachedTeacher') const cachedProfile = await AsyncStorage.getItem('@cachedProfile') // 所有缓存都存在时直接使用缓存,不发起请求 if (cachedParent && cachedStudent && cachedTeacher && cachedProfile) { setParent(JSON.parse(cachedParent)) // 其余缓存值同理赋值给对应状态 isFetchingRef.current = false return } const _token = await AsyncStorage.getItem('@token') const UserId = await AsyncStorage.getItem('@UserID') setToken(_token) // 并行处理所有请求 const [parentRes, studentRes, teacherRes, profileRes] = await Promise.all([ commonFetch('/Parents/Application/Access/10/', UserId, _token), commonFetch('/Student/对应的接口后缀/', UserId, _token), commonFetch('/Teacher/对应的接口后缀/', UserId, _token), commonFetch('/UserProfile/对应的接口后缀/', UserId, _token) ]) // 请求成功后赋值状态并写入缓存 if (parentRes) { setParent(parentRes) await AsyncStorage.setItem('@cachedParent', JSON.stringify(parentRes)) } // 其余返回值同理处理 isFetchingRef.current = false }) return () => { task.cancel() isFetchingRef.current = false } }, [])
5. 高频触发场景添加防抖/节流
如果这类请求是由用户操作(如输入搜索、滚动加载、频繁切换tab)触发的,可以添加防抖(操作停止后N毫秒再发请求,比如300ms)或节流(N毫秒内最多发1次请求)逻辑,避免短时间内触发大量请求。
相关运行截图:
内容的提问来源于stack exchange,提问作者May Yie
相关产品推荐
相关产品推荐

