Reputation: 41
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
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
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)
(I think they actually mean preload next and previous image, if I check other examples and demo's)
loadPrevNextAmount
(number, default: 1)
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