概要
Swiperには画像の遅延読み込みモードが標準で付いている。
以下のように設定することで、事前の全画像読み込みは控えつつ、今いるスライドの前後のスライドの画像だけロードしてくれるようになる。
var mySwiper = new Swiper('.swiper-container', {
preloadImages: false,
lazy: {
loadPrevNext: true,
},
});
参考: https://swiperjs.com/api/#lazy
が、以下の条件の時、一つ前に表示されたループスライド(=本来の最後のスライド)の画像がうまく読み込みされなかった。
var mySwiper = new Swiper('.swiper-container', {
preloadImages: false,
lazy: {
loadPrevNext: true,
},
loop: true,
slidesPerView: 3.33,
centeredSlides: true,
});
これを、最後のスライドは初期表示時に強制的に読み込まれるように設定した。
原因
色々試してみた結果、 loop: true
かつ slidesPerView
を整数以外で指定していると起こる現象のようだった。
加えて今回は centeredSlides: true
を付けていたことで、未ロード状態のスライドがそのまま見えてしまっていた。
どの項目もデザイン上必要な設定だったため、最後のスライドだけJS側で最初に強制的に読み込むよう設定した。
やり方
以下のように設定することで、最後のスライドを読み込みできる。
尚、試したSwiperのバージョンは 5.4.5
。
var mySwiper = new Swiper('.swiper-container', {
preloadImages: false,
lazy: {
loadPrevNext: true,
},
loop: true,
slidesPerView: 3.33,
centeredSlides: true,
on: {
init: function() {
this.lazy.loadInSlide(this.activeIndex - 1);
},
},
}
簡単な解説
this.lazy.loadInSlide(index)
は任意のスライドインデックス番号を入れて強制的にそのスライドの画像をロードできる関数。
ループ処理しないのであれば、ここに本来のスライド番号(=最後の番号)を入れれば良いが、
ループ処理中に実際に表示されるのは複製されたスライドのため、複製分だけスライド番号がずれて指定される。
そのため、 this.activeIndex
でループ時におけるスライド番号を取得し、その一つ前である最後のスライドを読み込み指定されるようにした。
その他の方法
何らかの理由で init
で処理を行いたくない場合は、以下のようにもできる。
var mySwiper = new Swiper('.swiper-container', {
//...略,
on: {
slideChange: function() {
if (this.realIndex === 0) {
this.lazy.loadInSlide(this.activeIndex - 1);
}
}
},
}
this.realIndex
で、ループの複製前の本来のスライド番号が取得できるので、
そこで0番目のインデックスのときに最後のスライドの画像のロード処理を行う。
感想
そもそも発生条件が稀なのか、検索しても類似情報がヒットせず解決に苦労した。
公式のこのあたりのissueの投稿が参考になった。
lazy pre loading for images in loop mode · Issue #2780 · nolimits4web/swiper
Swiper doesn't load the last slide? · Issue #3315 · nolimits4web/swiper