场景
需要在一个swiper加载将近500个动态canvas,并且要自动轮播。
解决方案:
方案一:只加载显示的几个item,看不见的只加载 简单的item。(因为加载的动态的canvas重复的加载卸载组件也会 非常卡顿,所以这个方法不合适)
const setSwiperSlide = (e: any) => {
// console.log('realIndex', e.realIndex);
setMarkNum(e.realIndex);
};
<Swiper spaceBetween={0} slidesPerView={3} onSlideChange={setSwiperSlide} autoplay={{ disableOnInteraction: false, delay: 6000 }}>
{classData.length > 0 &&
classData.map((item: IClassData, index: number) => {
if ([markNum - 1, markNum, markNum + 1, markNum + 2, markNum + 3].includes(index)) {
return (
<SwiperSlide key={index}>
<div className={style.liquidFill} id="liquidFill1">
<WaveGlobe
rate={(item.ATTENDANCE_COUNT / item.PEOPLE_TOTAL).toFixed(2)}
course={item.COURSE_NAME}
rateString={item.ATTENDANCE_RATE}
></WaveGlobe>
</div>
</SwiperSlide>
);
} else {
return <SwiperSlide key={index}></SwiperSlide>;
}
})}
</Swiper>
方案二:只用5个item去循环显示,然后动态的更新数据。
(用5个item是因为中间要显示3个,所以要多一个记录前一个的数据,一个记录后面的数据。)
const swiperItems = [0, 1, 2, 3, 4];
// 滑块向前滑动后
const SlidePrevTransitionEnd = (e: any) => {
if (prevMarkNum - 1 < 0) {
mySwiper.current.firstChild.swiper.slideToLoop(2, 0, false);
return;
}
if (e.realIndex == 3) {
chartData[2] = courseAttendance[prevMarkNum - 1];
} else if (e.realIndex == 4) {
chartData[3] = courseAttendance[prevMarkNum - 1];
} else if (e.realIndex == 0) {
chartData[4] = courseAttendance[prevMarkNum - 1];
} else if (e.realIndex == 1) {
chartData[0] = courseAttendance[prevMarkNum - 1];
} else if (e.realIndex == 2) {
chartData[1] = courseAttendance[prevMarkNum - 1];
}
setMarkNum((e) => e - 1);
setPrevMarkNum((e) => e - 1);
};
// 滑块向后滑动后
const SlideNextTransitionEnd = (e: any) => {
if (markNum == courseAttendance.length - 1) {
setMarkNum(0);
setPrevMarkNum(-1);
}
if (e.realIndex == 3) {
chartData[1] = courseAttendance[markNum];
chartData[2] = courseAttendance[prevMarkNum + 1];
} else if (e.realIndex == 4) {
chartData[2] = courseAttendance[markNum];
chartData[3] = courseAttendance[prevMarkNum + 1];
} else if (e.realIndex == 0) {
chartData[3] = courseAttendance[markNum];
chartData[4] = courseAttendance[prevMarkNum + 1];
} else if (e.realIndex == 1) {
chartData[4] = courseAttendance[markNum];
chartData[0] = courseAttendance[prevMarkNum + 1];
} else if (e.realIndex == 2) {
chartData[0] = courseAttendance[markNum];
chartData[1] = courseAttendance[prevMarkNum + 1];
}
setChartData(chartData);
setMarkNum((e) => e + 1);
setPrevMarkNum((e) => e + 1);
};
<Swiper
loop
spaceBetween={0}
slidesPerView={3}
onSlidePrevTransitionEnd={SlidePrevTransitionEnd}
onSlideNextTransitionEnd={SlideNextTransitionEnd}
autoplay={{ disableOnInteraction: false, delay: 5000 }}
>
{chartData.length > 0 &&
swiperItems.map((item: any, index: number) => {
return (
<SwiperSlide key={index}>
<div className={style.liquidFill} id="liquidFill1">
<WaveGlobe
rate={(chartData[index].ATTENDANCE_COUNT / chartData[index].PEOPLE_TOTAL).toFixed(2)}
course={chartData[index].COURSE_NAME}
rateString={chartData[index].ATTENDANCE_RATE}
></WaveGlobe>
</div>
</SwiperSlide>
);
})}
</Swiper>
缺点:一下滑动只能滑过一个item,要是划过两个会导致数据混乱,所以必要可以限制滑动的距离。
性能提升:cpu占用50% => cpu占用30%,提升20%多的性能。