画像の遅延読み込みにloading属性とJavaScriptを併用した最大限のパフォーマンスを発揮させる実装方法
Post on:2020年9月10日
画像やiframeの遅延読み込みに使用するloading属性と非サポートブラウザ用にJavaScriptを併用した現代的なアプローチで、最大限のパフォーマンスを発揮させる実装方法を紹介します。
Best way to lazy load images for maximum performance
by Adrian Bece
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
画像の遅延読み込みは比較的簡単に実装でき、パフォーマンスを大幅に向上させることができるため、Webサイトを最適化するために使用される選択肢の1つです。遅延読み込みでは画像を非同期で読み込みます。つまり、画像がブラウザのビューポートに表示されたときにのみ読み込むようにします。
ちょうど1年ほど前に、画像やiframeでネイティブの遅延読み込み機能がChromeやその他の主要なブラウザ向けにリリースされました。この機能の注目点は、ブラウザが画像やiframeをリクエストするタイミングを制御できるようになったことで、実装が少し楽になりました。それ以前は、JavaScriptでビューポートの変更を監視して動的にリソースを読み込む方法しかなかったからです。
参考: Chromeに実装される新機能『loading属性』について解説、ついにブラウザがネイティブで遅延ロードをサポート
この記事の執筆時点では、ネイティブの遅延読み込み機能はブラウザの約73%がサポートしており、これはまぁ悪くない数字ですが、27%の潜在的なユーザーがこの機能を使えない状態にしてしまうのは避けたいところです。
現在のサポート状況を踏まえて、実装ポイントをまとめてみました。
- サポートしているブラウザでは、ネイティブの遅延読み込みを使用。
- サポートしていないブラウザでは、フォールバックとしてJavaScriptを使用。
- ブラウザがサポートしている場合、JavaScriptを読み込ませたくない。
- imgとsource要素の両方をサポートすることは必須。
遅延読み込みのloading属性とは
loading属性に使用できる値は3つあります。
-
- loading="auto"
- デフォルト値。属性を設定しないのと同じです。
-
- loading="eager"
- リソースをすぐに読み込みます。
-
- loading="lazy"
- ビューポートに表示されたら、リソースを読み込みます。
使用するケースにもよりますが、一般的にはファーストビュー(折り目より上)に表示されるリソースにはeager値を定義し、ファーストビューより下のリソースにはlazy値を定義します。
遅延読み込みの現代的なアプローチ
HTMLドキュメントが読み込まれた後に実行されるJavaScriptを記述する必要があります。私はJekyllを使用して、HTMLのbody要素の最後に追加されるJavaScriptをインクルードとして追加しています。これはレンダリングのブロックを回避するためにJavaScript関数を実行する最も効果的な方法です。
画像のマークアップ
ネイティブの遅延読み込み機能のサポートに基づいて画像の読み込み処理を開始するJavaScript関数が必要です。これを実現するためには、画像のパスをsrcの代わりに、data-srcに記述します。ただし、srcを空にしてはいけないので、1x1pxの透明な画像のプレースホルダーを使用します。
img要素のマークアップは下記のようになります。
1 2 3 4 5 6 7 |
<img src="/path/to/placeholder/image.png" data-src="/path/to/full/image.jpg" alt="Image description" class="lazyload" loading="lazy" /> |
class="lazyload"は、フォールバックのJavaScriptによって与えられることに注意してください。私はこのclassを付与するlazysizesを使用しています。
また、複数のsource要素とフォールバックのimg要素を含むpicture要素にも対応したいと思います。
1 2 3 4 5 6 7 8 9 10 |
<picture> <source data-srcset="path/to/image.webp" type="image/webp" /> <source data-srcset="path/to/image.jpg" /> <img loading="lazy" class="lazyload" src="path/to/placeholder/image.png" data-src="path/to/image.jpg" alt="Image description" /> </picture> |
機能の検出
ユーザーが使用しているブラウザでネイティブの遅延読み込みをサポートしているかどうかを検出する必要があります。検出は、JavaScriptで簡単にできます。
1 2 3 4 5 |
if ("loading" in HTMLImageElement.prototype) { /* ネイティブの遅延読み込みをサポートしている場合 */ } else { /* ネイティブの遅延読み込みをサポートしていない場合 */ } |
JavaScriptの最終コード
ネイティブの遅延読み込みで必要なのは、imgとsource要素のsrc値にdata-src値を割り当てるだけで、残りの処理はブラウザに任せることができます。
サポートされていないブラウザには、JavaScriptを使用します。私はlazysizesを使用しましたが、他のプラグインでも大丈夫です。あとは、マークアップ(class名やdata要素など)が正しいことを確認してください。
JavaScriptの最終コードは下記のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<script> if ("loading" in HTMLImageElement.prototype) { var images = document.querySelectorAll('img[loading="lazy"]'); var sources = document.querySelectorAll("source[data-srcset]"); sources.forEach(function (source) { source.srcset = source.dataset.srcset; }); images.forEach(function (img) { img.src = img.dataset.src; }); } else { var script = document.createElement("script"); script.src = "/link/to/lazyload.js"; document.body.appendChild(script); } </script> |
パフォーマンスとLighthouseスコアの向上
私の個人サイトで遅延読み込みのこの現代的なアプローチを使用したところ、Lighthouseスコアと全体的なパフォーマンスが向上しました。
Lighthouseスコア
最大のパフォーマンスを得るための画像最適化テクニック
遅延読み込みは、画像のパフォーマンスを最適化する方法の1つです。CDNやプログレッシブ画像などを使用したWeb固有の画像形式など、Webにおける画像最適化の重要なテクニックと側面を解説した記事をご覧ください。
Optimizing images for the web - an in-depth guide
ここまで読んでくれて、ありがとうございます。
この記事があなたのお役にたてば嬉しいです。
sponsors