Matthias
Matthias

Reputation: 41

lazyloading swiper.js preloading the next image?

Is there a way to preload the next or two next images with a swiper.js while lazyloading is active?

The slider contains 100 images which we don’t want to load while the page opens for obvious reasons but we want the first and the two next images to be loaded to have them present within the next slide while the animation runs.

any ideas?

Upvotes: 4

Views: 23797

Answers (2)

Rodrigo López Dato
Rodrigo López Dato

Reputation: 1454

Since version 9, Swiper does not have a lazy loading API and instead leverages browsers' native lazy loading functionality:

Since version 9 Swiper doesn't have specifid lazy loading API, as it relies on native browser lazy loading feature. To use lazy loading, we just need to set loading="lazy" on images and add preloader element

loadPrevNextAmount is gone from the API. One way to achieve similar behavior is to use the slideChange event to force the next N images to load by setting their loading attribute to eager (assuming they were originally set as lazy and each slide element has a single image you want to preload):

const swiper = new Swiper('.swiper', { ... });
const preloadNext = (n) => {
    swiper
        .slides
        .slice(swiper.activeIndex, swiper.activeIndex + n + 1)
        .map(slide => slide.querySelector('img'))
        .forEach(s => s.setAttribute('loading', 'eager'));
};

// preload the next 2 images immediately
preloadNext(2);

// preload the next 2 images after changing slides
swiper.on('slideChange', () => preloadNext(2));

Another possible optimization is to wait for the page to fully load, which includes the first image in the swiper, and only then preload the following images. This avoids loading the first 3 images at the same time in order to display the first image faster:

let swiper;
const preloadNext = (n) => {
    swiper
        .slides
        .slice(swiper.activeIndex, swiper.activeIndex + n + 1)
        .map(slide => slide.querySelector('img'))
        .forEach(s => s.setAttribute('loading', 'eager'));
};
document.addEventListener('DOMContentLoaded', () => {
    swiper = new Swiper('.swiper', { ... });
    swiper.on('slideChange', () => preloadNext(2));
});
window.addEventListener('load', () => {
    preloadNext(2);
});

Upvotes: 5

Anwi77
Anwi77

Reputation: 109

I am looking for the same thing, and looking at the swiperJS documentation, I stumbled upon the API settings for lazyloading.

Looks like maybe loadPrevNext and loadPrevNextAmount might help us out.

loadPrevNext (boolean, default:false)

  • Set to true to enable lazy loading for the closest slides images (for previous and next slide images)

(I think they actually mean preload next and previous image, if I check other examples and demo's)

loadPrevNextAmount (number, default: 1)

  • Amount of next/prev slides to preload lazy images in. Can't be less than slidesPerView

So:

const swiper = new Swiper('.swiper-container', {
  lazy: {
    loadPrevNext: true, // pre-loads the next image to avoid showing a loading placeholder if possible
    loadPrevNextAmount: 2 //or, if you wish, preload the next 2 images
  },
});

Upvotes: 5

Related Questions