You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js13.3+中Swiper v10图片懒加载一次性加载问题

问题

在Next.js 13.5项目中使用Swiper v10时,给12个<SwiperSlide>内的图片添加了loading="lazy"属性,示例代码如下:

<SwiperSlide>
    <img src="/images/1.png" loading="lazy" width="1200" height="800" alt="image" />
    <div className="swiper-lazy-preloader swiper-lazy-preloader-white"></div>
</SwiperSlide>
<SwiperSlide>
    <img src="/images/2.png" loading="lazy" width="1200" height="800" alt="image" />
    <div className="swiper-lazy-preloader swiper-lazy-preloader-white"></div>
</SwiperSlide>
// 剩余10个Slide结构一致

同时Swiper初始化配置已开启lazy={true}:

<Swiper
    ref={slides}
    effect="cards"
    grabCursor={true}
    modules={[Controller, EffectCards, Mousewheel]}
    lazy={true}
    loop={true}
    speed={600}
    direction="horizontal"
    mousewheel={{
        forceToAxis: true,
        invert: true,
        thresholdDelta: 6,
        sensitivity: .2
    }}
    edgeSwipeDetection="prevent"
    controller={{ control: controlledSwiper }}
    className={sectionInters ? `worksSwiper ${styles.worksSwiper} ${styles.visible}` : `worksSwiper ${styles.worksSwiper}`}
>

实际运行时,页面滚动到滑块区域后,所有图片会一次性完成懒加载,而非切换到对应幻灯片时才加载。

原因分析

  • 双懒加载机制冲突:同时启用了浏览器原生loading="lazy"和Swiper内置懒加载,且Swiper的cards特效会让所有Slide初始时处于视口堆叠状态,浏览器检测到所有图片都在视口范围内,就会一次性触发加载。
  • 未遵循Swiper懒加载DOM规范:当前图片写法不符合Swiper懒加载的要求,导致Swiper无法接管图片加载逻辑,只能由浏览器原生机制处理。

解决方法

1. 移除浏览器原生懒加载属性

删除所有<img>标签上的loading="lazy",避免与Swiper懒加载逻辑冲突。

2. 按照Swiper规范修改图片结构

将图片的src替换为data-src,并给<img>添加swiper-lazy类,这是Swiper懒加载识别目标元素的必要条件:

<SwiperSlide>
    <img data-src="/images/1.png" width="1200" height="800" alt="image" className="swiper-lazy" />
    <div className="swiper-lazy-preloader swiper-lazy-preloader-white"></div>
</SwiperSlide>
<SwiperSlide>
    <img data-src="/images/2.png" width="1200" height="800" alt="image" className="swiper-lazy" />
    <div className="swiper-lazy-preloader swiper-lazy-preloader-white"></div>
</SwiperSlide>
// 剩余Slide按此格式修改

3. 完善Swiper配置

  • 确保在modules数组中导入Lazy模块,否则Swiper懒加载功能无法生效;
  • 开启preloadImages={false}禁用全局预加载,配合lazyPreloadPrevNext按需预加载前后Slide的图片(比如设置为1,仅预加载当前Slide的前后各一个):
<Swiper
    ref={slides}
    effect="cards"
    grabCursor={true}
    modules={[Controller, EffectCards, Mousewheel, Lazy]} // 新增Lazy模块
    lazy={true}
    preloadImages={false} // 关闭全局预加载
    lazyPreloadPrevNext={1} // 按需预加载前后Slide
    loop={true}
    speed={600}
    direction="horizontal"
    mousewheel={{
        forceToAxis: true,
        invert: true,
        thresholdDelta: 6,
        sensitivity: .2
    }}
    edgeSwipeDetection="prevent"
    controller={{ control: controlledSwiper }}
    className={sectionInters ? `worksSwiper ${styles.worksSwiper} ${styles.visible}` : `worksSwiper ${styles.worksSwiper}`}
>

内容的提问来源于stack exchange,提问作者Nathan Bernard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:13:30