Web パフォーマンスを考えていく上で、最初にアプローチするのがネットワーク処理の最適化になるだろう。ネットワーク処理というのは、リクエストを減らす だとか ペイロードサイズを減らす といった話である。
中でも、特に画像はネットワークトラフィックの大半を占めている。私は自社の Web サービスのパフォーマンス改善に取り組んできたが、どの Web サービスにおいても画像が多いだけでなく、減色 とか メタ情報の削除 といったような初歩的な最適化が出来ていないことが多い。画像の最適化に関しては Webにおける画像の最適化について考える とか 画像の最適化をCLIだけで行うgrunt-imageを作った を見てもらうとして、この記事では画像をスクロール同期でロードするアプローチについて解説する。
スクロール同期でロードするメリット
ユーザーの視認領域に近づくまで画像のリクエストが発生しないので、HTTP リクエストが発生しない。つまり、スクロールされない限りは画像のダウンロードが行われないので、ユーザーのネットワーク処理に優しいだけでなく、ブラウザの処理に関しても HTTP リクエストを行わない分、他の処理を実行できる。
ページロードのタイミングでユーザーの目に最初に入る領域(= Above The Fold)に画像があれば、当然いち早くコンテンツを届けなければいけない。この ATF に重要なコンテンツを置くのは当然の発想で、他の画面への導線なども集中していることが多い。言い換えれば、下までスクロールされないことも多々あるだろう。そういうコンテンツの優先度を考慮してもそれなりに有効な手段と言えるだろう。
<img>
要素の loading
属性
スクロールに同期して画像をロードしたいときに、旧来のアプローチとしては 1000ch/lazyload のようなライブラリを使ってスクロールイベントを監視したり、IntersectionObserver を使って要素がビューポートに入ったかどうかを監視することで実現してきた。
しかし HTML の仕様として実現できるように <img>
要素(と <iframe>
要素)に loading
属性が追加された。loading
属性は以下の3つの値を取ることができる。
-
eager
: 遅延ロードしない -
lazy
: 遅延ロードする -
auto
: ブラウザに判断を委ねる
つまり、遅延ロード(スクロールに応じてロード)させたい画像に対しては、以下のように loading="lazy"
属性を <img>
要素に付与することで実現できる。
<img src="image.png" loading="lazy" alt="">