一、提起网络请求优化,可能我们能想到很多方案
- 减少 HTTP 请求的方法,如合并文件、雪碧图、懒加载等。
- 减少页面加载时间的技术,如资源压缩、使用 CDN 加速等。
- 优化网络传输的方法,如使用 HTTP/2、减少请求大小等。
- 减少请求数量。通过合并多个资源文件(如CSS、JavaScript、图像等),减少HTTP请求的数量。
- ……………………………………等,就不在一一列举
二、以减少请求数量来举例进行代码实施**
1、场景:在我所做的可视化大屏项目中、会开发很多组件、然后将其拖拽至内容区域、对其去做http请求配置、或数据集配置;
但是这些组件他们配置的接口及其参数都是相同的、假设有10个、20个只是样式不同的组件都用到了同样的接口,那本来一次请求就可以、却发了20次;
2、解决方案:其实如果是普通项目、我们可能会将其请求直接提升到状态管理中的action中、数据也存储在store中、判断如果有数据就不做请求、当然其实这样也不对,如果一直缓存,而后端有更新呢;而且本身项目组件亦是动态、我会记录列一种开发思想下的实现、当然一下代码全部为简化demo代码
3、实操: 我们可以设计一个全局数据池的概念、初始化是为空数组、在组件调用hook时、那就把当前组件id和拿到请求结果的callback传递到数据池hook当中;
假设A、B、C组件用到了一个公共接口、那就以这个公共数据池id为’ABC_buisness_1’,(当让组件id、数据池id肯定是动态、我们当前为了简单先以静态讲解)
// A组件
import { useChartDataPondFetch} from '@/hooks'
const { addGlobalDataInterface } = useChartDataPondFetch()
addGlobalDataInterface(
{id:"A组件",requestDataPondId:"ABC_buisness_1"},
(res)=>{console.log('拿到请求的结果',res)
)
以’ABC_buisness_1’为数据池map的key,以{组件id:A.id,更新回调:callback}为值;去创建这样的数据结构;
//useChartDataPondFetch.hook
// 数据池 Map 中请求对应 callback
const fetchABC_buisness_1 = ()=>fetch('xxxxx')
// 数据池
const mittDataPondMap = new Map()
// 数据池id对应的方法
const miitPondFetchMap = {
ABC_buisness_1: fetchABC_buisness_1
}
// 创建单个数据项轮询接口
const newPondItemInterval = (
requestDataPondItem,
dataPondMapItem
) => {
try {
const res = await requestDataPondItem()
// 遍历更新回调函数
dataPondMapItem.forEach(item => {
item.updateCallback(newFunctionHandle(res))
})
}
} catch (error) {
return error
}
}
/**
* 数据池接口处理
*/
export const useChartDataPondFetch = () => {
// 新增全局接口
const addGlobalDataInterface = (
targetComponent,
updateCallback
) => {
// 组件对应的id 以及数据池Id
const { id ,requestDataPondId} = targetComponent
// 新增数据项
let mittPondIdArr = mittDataPondMap.get(requestDataPondId) || []
mittPondIdArr.unshift({
id,
updateCallback,
})
const map = new Map();
mittPondIdArr = mittPondIdArr.filter(
item => !map.has(`${item.id}`) && map.set(`${item.id}`,true)
);
mittDataPondMap.set(requestDataPondId, mittPondIdArr)
}
// 清除旧数据
const clearMittDataPondMap = () => {
mittDataPondMap.clear()
}
// 初始化数据池
const initDataPond = () => {
for (let pondKey of mittDataPondMap.keys()) {
// 取出对应数据池id对应的请求方法
const requestDataPondItem = miitPondFetchMap[pondKey]
if (requestDataPondItem) {
newPondItemInterval(requestDataPondItem, mittDataPondMap.get(pondKey))
}
}
}
return {
addGlobalDataInterface,
clearMittDataPondMap,
initDataPond
}
}
然后在最外层组件中初始化数据池,当进入最外层组件的onMounted的时候,每个子组件已经走了render,该添加数据池的,也已经添加到了数据池mittDataPondMap 中;此时直接进行循环调用,把每一个数据池id对应的方法全部执行一遍、拿到结果再把对应每个组件的回调在执行一遍、此时就达到了我们想要的效果;
const { initDataPond, clearMittDataPondMap } = useChartDataPondFetch()
clearMittDataPondMap()
onMounted(()=>{
initDataPond();
})
4、总结:
1、组件中添加自己的id、及对应数据池id和请求回调到数据池中;
add({
id:'自定义id',
requestDataPondId:"自定义数据池id",
callback:"请求结果回调"
)
2、定义数据池方法Map
// 数据池id对应的方法
const miitPondFetchMap = {
ABC_buisness_1: fetchABC_buisness_1
}
3、外层组件初始化循环
const initDataPond = () => {
for (let pondKey of mittDataPondMap.keys()) {
// 取出对应数据池id对应的请求方法
const requestDataPondItem = miitPondFetchMap[pondKey]
if (requestDataPondItem) {
newPondItemInterval(requestDataPondItem, mittDataPondMap.get(pondKey))
}
}
}
4、创建请求、遍历执行回调
const newPondItemInterval = (
requestDataPondItem,
dataPondMapItem
) => {
try {
const res = await requestDataPondItem()
// 遍历更新回调函数
dataPondMapItem.forEach(item => {
item.updateCallback(newFunctionHandle(res))
})
}
} catch (error) {
return error
}
}