WebPとLazyLoadを使って表示速度を向上させる
ホームページの表示速度を上げるには、デバイスごとの画像ファイルの切り替えが有効です。画像フォーマットのWebPと、LazyLoadで遅延読み込みで、表示速度を体感できるパフォーマンスにします。
表示速度が異常に遅いホームページはSEOにも不利になることから、近頃はホームページの表示速度に関してセンシティブになっています。
ホームページの表示が遅い主な原因は画像ファイルの読み込みです。
今回は、PCとスマートフォンそれぞれに最適な画像ファイルを読み込むようにします。
さらにLazyLoadを使って遅延読み込みさせて表示速度を早めます。
また、画像ファイルに「WebP」フォーマットを使って、画像の軽量化を図ります。WebPフォーマットが対応しているブラウザにはWebP画像を表示させ、未対応のブラウザには通常のjpgやpng画像を表示させます。
- デバイスに合わせたサイズの画像を読み込む
- LazyLoadで、スクロールに合わせて画像を読み込む
- WebP画像に対応しているブラウザには、WebPを表示させる
完成したソース
LazyLoadとWebPの完成したソースはこちらになります。 Webpの記述がありませんが、JavaScriptが追記してくれます。
JavaScript
<script src="picturefill.min.js"></script>
<script>
(function(w, d){
var b = d.getElementsByTagName('body')[0];
var s = d.createElement("script");
var v = !("IntersectionObserver" in w) ? "8.17.0" : "10.19.0";
s.async = true;
s.src = "https://cdn.jsdelivr.net/npm/vanilla-lazyload@" + v + "/dist/lazyload.min.js";
w.lazyLoadOptions = {
elements_selector: ".lazy",
to_webp:true
};
b.appendChild(s);
}(window, document));
<script>
HTML
<img class="lazy" data-src="image@1x.jpg"
data-srcset="
image@1x.jpg 1x,
image@2x.jpg 2x,
"
alt="画像"
>
PC、スマートフォンの画像切り替え
デバイスによって表示させる画像を切り替えるには「picture」と「srcset」タグを利用します。
srcsetタグの良い点は、複数の画像を用意しても最適な画像のみを読み込むところです。
デバイスごとに表示させる画像を変更する場合は、srcsetタグはとても便利です。
srcsetタグ
まずはsrcsetタグを使ってみます。
srcsetは、IE以外のブラウザに対応しています。Can I use IEに対応させるには後述しているpicturefillを読み込めばIEでもsrcsetタグが利用できます。
HTML
<img src="image.jpg"
alt="説明"
srcset="image-640.jpg 640w,
image-320.jpg 320w"
>
画面サイズが320までは「image-320.jpg」が表示され、320以上は「image-640.jpg」が表示されます。
今度はディスプレイの解像度によって画像を切り替えてみます。
HTML
<img src="image.jpg"
alt="説明"
srcset="image-640.jpg 2x,
image-320.jpg 1x"
>
通常のディスプレイは「image-320.jpg」が表示され、Retinaディスプレイは「image-640.jpg」が表示されます。
pictureタグ
pictureタグを使うことで、ウインドウサイズごとに画像を切り替えることができます。
pictureタグもIE以外のブラウザに対応しています。Can I use
HTML
<picture>
<source srcset="image-640.jpg" media="(min-width: 640px)">
<source srcset="image-320.jpg" media="(min-width: 320px)">
<img srcset="image.jpg" alt="説明">
</picture>
ウインドウサイズが320からは「image-320.jpg」が表示され、640以上は「image-640.jpg」が表示されます。
pictureタグとsrcsetタグを組み合わせることもできます。
HTML
<picture>
<source srcset="image-640@2x.jpg 2x, image-640.jpg 1x" media="(min-width: 640px)">
<source srcset="image-320@2x.jpg 2x, image-320.jpg 1x" media="(min-width: 320px)">
<img srcset="image.jpg" alt="説明">
</picture>
上記の設定ではウインドウサイズとディスプレイ解像度から最適な画像を表示されます。
ウインドウサイズが320でRetinaディスプレイの場合は「image-320@2x.jpg」が表示されます。
srcsetとpictureの挙動の違い
srcsetは、ディスプレイのサイズや解像度によって画像が切り替わります。
pictureは、ブラウザのウインドウサイズによって画像が切り替わります。
つまり、ブラウザの幅を変えていくとpictureタグはブレイクポイントで画像が切り替わりますが、srcsetタグは画像が切り替わりません。
そのためpictureタグは、スタイルシートでbodyサイズを1000pxに固定しても、ブラウザサイズを1000px以下にどんどん縮めていくとブレイクポイントで画像が切り替わります。
IEにも対応させるpicturefillを使う
IEは、picture、srcsetタグに対応していないため、Picturefillを読み込みます。
HTML
<script src="https://cdn.rawgit.com/scottjehl/picturefill/3.0.2/dist/picturefill.min.js"></script>
あとは同じようにsrcsetタグやpictureタグを使うとOKです。
HTML
<img src="image.jpg"
alt="説明"
srcset="image-640.jpg 640w,
image-320.jpg 320w"
>
picturefillを利用するとディスプレイの解像度も解析して最適な画像を表示してくれます。
例えば、上記のサンプルを画面サイズ320のRetinaディスプレイで表示させると「image-320.jpg」ではなく、「640.jpg」を表示してくれます。エライ!
遅延読み込みするLazyLoadを使う
LazyLoadのスクリプトはいろいろありますが、このLazyLoadはjQueryに依存しません。 もちろん「picture」「srcset」タグにも対応しており、自動的に「WebP」のソースを追加してくれます。コレは便利です。
</body>より後にlazyload.jsを読み込みます。
JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/10.10.0/lazyload.min.js"></script>
<script>
var myLazyLoad = new LazyLoad({
elements_selector: ".lazy"
});
</script>
IEに対応するにはLazyLoadのバージョン8を使います。 下記スクリプを記述することで、ブラウザによってバージョン8と10を読み分けてくれます。
JavaScript
<script>
(function(w, d){
var b = d.getElementsByTagName('body')[0];
var s = d.createElement("script"); s.async = true;
var v = !("IntersectionObserver" in w) ? "8.8.0" : "10.10.0";
s.src = "https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/" + v + "/lazyload.min.js";
w.lazyLoadOptions = {};
b.appendChild(s);
}(window, document));
</script>
LazyLoadを使ったsrcsetの場合は下記になります。
HTML
<img class="lazy" data-src="img.jpg"
data-srcset="image-320.jpg 320w,
image-640.jpg 640w"
alt="画像"
>
LazyLoadを使ったpictureの場合は下記になります。
HTML
<picture>
<source media="(min-width: 640px)" data-srcset="image-640.jpg" />
<source media="(min-width: 320px)" data-srcset="image-320.jpg" />
<img class="lazy" src="image.jpg" alt="画像">
</picture>
min-widthを使う場合は、大きなサイズから記載します。
画像フォーマットWebPの導入
Googleが開発した画像フォーマットです。 非可逆圧縮により軽量で綺麗、アルファチャンネルも扱えるのが特徴です。
jpgとWebPのファイルサイズを比べると、1/5から1/3ぐらいまでサイズをダイエットできます。 100KBのファイルが20KB前後になるので、画像ファイルをかなりダイエットできます。
WebPに変換するには、gulpのプラグイン「gulp-webp」または、ソフト「webpconv」などで画像をWebPに変換できます。
PhotoShopのWebPプラグインもあります。
Safari以外のブラウザの多くがWebPに対応しています。Can I use
WebPを使ってみる
WebPを実際に使ってみます。
</body>タグの後に下記を記載します。
JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/10.10.0/lazyload.min.js"></script>
<script>
var myLazyLoad = new LazyLoad({
elements_selector: ".lazy",
to_webp:true
});
</script>
<script src="https://cdn.rawgit.com/scottjehl/picturefill/3.0.2/dist/picturefill.min.js"></script>
あとは、画像はpictureでラッピングすればOKです。
HTML
<picture>
<source media="(min-width: 1000px)" data-srcset="image-1000.jpg" />
<source media="(min-width: 640px)" data-srcset="image-600.jpg" />
<img class="lazy" src="image.jpg" alt="画像">
</picture>
WebPのソースは不要です。JavaScriptが自動的にソースを追記してくれます。
srcsetを使う場合は下記になります。
HTML
<img class="lazy" data-src="image@1x.png"
data-srcset="
image@1x.png 1x,
image@2x.png 2x,
"
alt="画像です"
>
こちらもWebPのソースは不要です。WebPのソースを記述するとEDGEではエラーとなります。
写真が多いホームページでは体感できる速さになると思います。
amp-imgを使った表示切り替えとLazyLoad
amp-imgタグは、非AMPページでも使うことができます。また、amp-imgはLazyLoad機能を使うことができます。
詳しくはAMPのドキュメントで確認してください。
amp-imgはsrcsetが用意されていますが、pictureタグは未対応のようです。テストしましたが可動しませんでした。
WebPファイルをsrcsetで使った場合、FireFoxで画像が表示されません。IEはフォールバックの画像が表示されます。
AMPのnoscriptタグなどを使ってFireFoxでも画像を表示させることはできるかもしれませんが、運営コストがかかるのでパスします。
AMP用のjavascriptを読み込みます。
JavaScript
<script async src="https://cdn.ampproject.org/v0.js"></script>
あとは、amp-imgで画像ファイルを読み込みます。
HTML
<amp-img
src="img-640.jpg"
width="640" height="400"
layout="responsive"
alt="画像です">
</amp-img>
srcsetを使う場合は下記になります。
HTML
<amp-img
src="image.jpg"
width="640"
height="400"
layout="responsive"
alt="画像です"
srcset="img-640.jpg 640w,
img-320.jpg 320w"
>
</amp-img>
WebPを使わない場合は、amp-imgタグを使うのも便利だと思います。