swiper滑动优化、数据缓存处理

1,519 阅读3分钟

最近遇到的一个优化问题,记录一下。


场景: uniapp使用swiper渲染数据,只有三个swiper-item,目前是每次滑动都会去请求新的数据重新渲染当前item,卡顿很明显,需做优化;初始数据加载当前以及前后相邻两个数据,左滑或者右滑后,加载对应最新的一个数据,如果往回滑动,判断数据是否已经加载过,不再进行请求。

示例:

数据列表id:[1,2,3,4,5,6,7,8,9]

对应请求数据详细列表:[a,b,c,d,e,f,g,h,i]

我从数据列表单击某一个数据携带id进入到数据详情页面,当前做法为进入页面请求对应id的详细信息,再拿详细信息去请求对应的md文件进行页面的渲染,每次滑动都需要重新进行请求获取,造成页面会有明显的卡顿,体验不好,对这种情况进行一个优化。

思路:

1、首次进入页面后,初始化请求三个数据,将数据对应渲染到swiper-item上,滑动的时候,请求当前数据的下一个数据,并插入缓存数组,根据swiper当前最新的索引,更新swiper-item上对应的数据。还需要考虑数据小于3的情况。

1示例:进入 id为4的详情,初始化请求3,4,5的数据并缓存,并将3,4,5数据对应绑定到swiper-item 0,1,2上,默认显示为数据4页面,swiper索引为1,左滑到0,也就是数据3,进行请求数据2并插入缓存数组前面,右滑同理,并将 swiper-item上的数据替换为对应的 2,4 达到正常的效果,最后就是要考虑边界的问题,从头滑到尾 以及从尾滑到头的位置计算。

//对应三个swiper-item的数据
let article0 = null;
let article1 = null;
let article2 = null;
//数据缓存数组
let cacheData = [];
//获取3个初始化数据
const initData = async () => {
    try{
        //进入4详情,计算相邻id,此时应该初始化[3,4,5]
        const useIdArr = caleFileId();
        const filePromises = [], mdPromises = [];
        useIdArr.forEach(item => {
            filePromises.push(fetchFile({id:item.id})) 
        })
        const fileResults = await Promise.all(filePromises)
        fileResults.forEach(item => {
            mdPromises.push(fetchMd(item))
        })
        const mdResults = await Promise.all(mdPromises)
        cacheData = [...mdResults]
    }catch(err){
        console.log(err)
    }
}

//记录上一次位置
let oldCurrent = 0
//滑动方向
let direction = null
//swiper滑动监听, 以id 4 进入为例
const changeSwiper = async (e) => {
    const { current } = e.detail;
    if(current - oldCurrent  == 2 || current - oldCurrent == -1) {
        //第一次左滑,获取id为2,再次滑动则为1,后续同理,需考虑边界
        direction = 'left'
    }else if(current - oldCurrent  == 1 || current - oldCurrent == -2) {
        //第一次右滑,获取id为6,再次滑动为7,后续同理,需考虑边界
        direction = 'right'
    }
    
    //保存滑动位置记录
    oldCurrent = current;
    // id由上面滑动计算得到,进行请求
    fetchFile(id)
}

//文件请求
const getFile = async (id) => {
    //是否已做请求,存在缓存,拿缓存数据
    if(useIdArr.value.indexOf(id) > -1){
        caleDataLocation()
        return
    }
    const fileData = await fetchFile({id})
    const mdResult = await fetchMd(fileData)
    //加入缓存
    if(direction === 'left'){
        useIdArr.unshift(mdResult)
    }else{
        useIdArr.push(mdResult)
    }
    
    //进行swiper-item数据的替换
    caleDataLocation(id)
}

//进行计算当前对应swiper-item的数据
const caleDataLocation = (id) => {
    //根据direction方向、oldCurrent的位置,以及当前id在缓存中的位置计算替换前后两个item的数据
    
}

以上就是主要的实现方法,最后的结果可以达到预期效果;

有尝试过以动态的形态去实现,但是发现仍有问题,最后采用了这种办法;

大家有什么问题或者更好的想法欢迎讨论。