目に見える画像を読み込む
重要性: 4
低速のクライアントがおり、モバイルのトラフィックを節約したいとしましょう。
この目的に対し、画像をすぐには表示せず、それらをプレースホルダに置き換えることに決めました。次のようになります:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
なので、最初はすべての画像が placeholder.svg です。ユーザが画像を見ることができる位置までページがスクロールされたとき、-- src を data-src のものに変更します。そうすると画像が読み込まれます。
iframe に例があります:
画像を見るためにスクロールし、“要求があり次第” 読み込みます。
要件:
- ページが読み込まれると、スクロールする前に画面に表示されている画像はすぐに読み込まれます。
- 画像の中には、
data-srcがないものもあります。 コードはそれらに触れるべきではありません。 - 一旦ロードされた画像は、スクロールで画面内/外が変わってもそれ以上再読込されるべきではありません。
P.S. 可能であれば、現在の位置の1ページ前後にある画像を「プリロードする」より高度な解決策を作成してください。
P.P.S. 垂直スクロールのみが処理され、水平スクロールは処理されません。
onscroll ハンドラでどの画像が見えているのかを確認し、それらを表示する必要があります。
また、スクロールをする前にすぐに見える画像を検知してそれらを読み込むために、ページが読み込まれた時にもそれを実行したいです。
// ...the page content is above...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// top elem edge is visible OR bottom elem edge is visible
let topVisible = coords.top > 0 && coords.top < windowHeight;
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
showVisible();
window.onscroll = showVisible;
見えている画像に対して、img.dataset.src を取り、img.src に割り当てます(まだしていない場合)。
P.S. この解決策は1ページ上下にある画像を “プリロード” する isVisibe のバリアントも持っています(ページの高さは document.documentElement.clientHeight です)。