書いてあること
画像のみがたくさん並んでいるようなサイトで画像の遅延読み込みをするために、 lazysizes を使ったら素直に実装できたという話です。
実現したいこと
文章ではなく画像が主体のサイトを想像して下さい。たとえば、写真ライブラリーのようなサイトです。
画像の要件としては、レスポンシブ対応として、ある横幅より小さい場合はその横幅いっぱいで表示する、という物です。
その画像が縦にたくさん並んでいるような表示をしたいとします。
たとえば、画像の最大のサイズを横600ピクセルとする場合はこのような指定となります。
<div>
<img
src="hoge_600.jpg"
srcset="hoge_1200.jpg 1200w, hoge_600.jpg 600w, hoge_300.jpg 300w"
sizes="(max-width=600px) 100vw, 600px)"
>
</div>
<div>
<img
src="fuga_600.jpg"
srcset="fuga_1200.jpg 1200w, fuga_600.jpg 600w, fuga_300.jpg 300w"
sizes="(max-width=600px) 100vw, 600px)"
>
</div>
<div>
<img
src="piyo_600.jpg"
srcset="piyo_1200.jpg 1200w, piyo_600.jpg 600w, piyo_300.jpg 300w"
sizes="(max-width=600px) 100vw, 600px)"
>
</div>
このように画像が縦にたくさん並んでいるサイトにて画像の遅延読み込みをしたいです。
まず Vue-lazyload を試してみた
サイト作成で Vue.js を利用していたので、まずは Vue.js のプラグインを探したところ、 Vue-Lazyload を見つけたので試してみました。
話が少しそれますが、今回は画像のサイズが固定でないため、img タグに対して height
指定をしておらず、画像の読み込み前は img
タグの高さが0となっており、結果、すべての img タグが表示領域に入ってしまい、遅延読み込みになりませんでした。
そのため、Loading画像を用意して、画像読み込みまではその画像の高さを指定しようとしました。
その結果、Vue-Lazyload は、次の点で使いにくさがありました。
- 画像の読み込み完了するまではCSSで高さを指定しておきたかったが、画像の読み込みが始まるまでを指定できるCSSセレクタがなさそうでした。( 画像の読み込み中を指定するCSSセレクタはあった ) 参考
- sizes に対応していない。
どちらかというと後者が致命的でした。
前者は、最初は適当なクラスなどで高さを指定しておき、読み込み後のCSSでそれを打ち消すようにしておけばなんとかなりました。
後者は、sizesが使えないのでCSSで表示幅を指定したのですが、それですと srcset の中でどの画像ファイルを使うかが、表示幅ではなくブラウザの表示幅で決まってしまい、srcset の意味が失われそうです。
lazysizes を見つけた
Vue.js のプラグインではないのですが、 lazysizes を使うことにしました。
lazysizes は 先ほどの、Vue-Lazyload での使いにくさがありませんでした。
- 画像読み込みを始める前のCSSセレクタも指定できました。参考
- sizes も指定できます。
lazysizes を使うことで、画像が読みこまれるまでの画像にLoading画像を指定し、画像を読み込む前と画像読み込み中にLoading画像のサイズをCSS指定しておくだけで素直に実装できました。
<img
class="lazyload"
src="loading.png"
data-src="hoge_600.png"
data-srcset="hoge_1200.png 1200w, hoge_600.png 600w, hoge_300.png 300w"
sizes="(max-width: 600px) 100vw, 600px"
>
.lazyload, .lazyloading {
height: 300px;
}
というわけで lazysizes 助かりました。ありがとうございます。