IOS App内嵌H5 swiper 轮播出现卡顿白屏闪烁

发布时间 2023-08-11 15:47:09作者: 夏夜~

   话说在前头:前端开发同学遇到这个问题不慌,因为接下来你要踩的坑我都帮你们踩完了,所以有了这一篇博客。希望能帮到你

   轮播组件:swiper@4.5.1 (4x稳定的最后一个版本)

   设备:ios版本15x ,14和16版本都挺好的,问题仅在ios15的版本

   出现现象:左右滑动卡顿,不连手,放开的这一瞬间会卡一下。在同一部手机的safari或微信中没有这个问题,仅仅在app中有这个问题。

  一些案例:https://ask.csdn.net/questions/7544894   https://juejin.cn/post/7023231843004579877

  当然全都没有解决办法,只是都遇到。

  我试过了网上几乎所有办法,3x和5x版本都换过,无果...

  ok,网上找不到解决办法,老规矩,上github翻翻issue,有用,但不是特别有用。

  办法1: 升级5x版本,有个新增的属性  cssMode  这个属性开启后用现代CSS Scroll Snap API。它不支持Swiper的很多功能,但可能会带来更好的性能。 会将一些js复杂的运算和过渡用css来代替

  但是:少了很多功能(不推荐)

var mySwiper = new Swiper('.swiper-container', { cssMode: true });

  办法2:css启用硬件加速(但是只能解决白屏闪烁,卡顿依旧)

1 .swiper-slide{
2   -webkit-backface-visibility: hidden;
3   -webkit-transform: translate3d(0,0,0);
4 }
5 
6 .swiper-wrapper{
7   -webkit-transform-style: preserve-3d;
8 }

  办法3  https://github.com/nolimits4web/swiper/issues/4493

 1 function easeOut(currentTime, startValue, changeValue, duration) {
 2     currentTime /= duration;
 3     return -changeValue * currentTime * (currentTime - 2) + startValue;
 4 }
 5 
 6 function getTransitionSimulator(ele, distance, duration, callback) {
 7     let handle;
 8     let resolve;
 9     return () => {
10         let promise = new Promise(res => {
11             resolve = res;
12         });
13         let startTime = performance.now();
14         cancelAnimationFrame(handle);
15         function _animation() {
16             let current = performance.now();
17             // distance to move this frame
18             let disVal = easeOut(current - startTime, 0, distance, duration);
19 
20             callback(ele, disVal);
21             if ((current - startTime) / duration < 1) {
22                 handle = requestAnimationFrame(_animation);
23             } else {
24                 cancelAnimationFrame(handle);
25                 resolve();
26             }
27         }
28         handle = requestAnimationFrame(_animation);
29         return promise;
30     };
31 }
32 
33 swiper.on('setTranslate', (swiper, targetTransVal) => {
34     const wrapper = swiper.$wrapperEl[0]; // wrapper element
35     // when use transition to do animation
36     if (wrapper.style.transitionDuration !== '0ms') {
37         // get origin translate value
38         const curTransVal = this.swiper.getTranslate();
39         // cancel the animation of transition
40         wrapper.style.transitionDuration = '';
41         wrapper.style.transform = `translate3d(${curTransVal}px, 0px, 0px)`;
42 
43         // use requestFrameAnimation to do animation my self
44         const transSimulator = getTransitionSimulator(wrapper, targetTransVal - curTransVal, 300, (el, val) => {
45             el.style.transform = `translate3d(${curTransVal + val}px, 0px, 0px)`;
46         });
47         await transSimulator();
48         // End the transition, call the callback (simulate the internal implementation of Swiper)
49         swiper.onSlideToWrapperTransitionEnd.call(wrapper, { target: wrapper });
50 
51     }
52 })

    有用,但是只适用于整页整页滑动,多列并不是适用。

  办法4:用Mac电脑下载个xcode链接Iphone做一个Demo App 内嵌下你的H5 页面。看是否正常,如果正常的话。那毫无提问,问题不前端,让IOS开发去排查问题。顺利解决

  最后:我这边是ios开发定位到了,确实是App的某个地方影响了全局的轮播,卡了好多天的问题,唉~~,如果你们也遇到过,把你们的解决办法说一下吧!!