> makibishi throw|

lazysizesで色々な遅延読み込み

lazysizes とは

lazysizes は web ページ上の画像などの遅延読み込みをするためのライブラリです。 遅延読み込みとは「必要になるまでロードを行わない」ことを意味していて、web ページを構成する様々なものを遅延読み込みさせることで、ページの読み込み速度を改善できます。

web ページの遅延読み込みを行うライブラリはlazyloadvanilla-lazyloadをはじめ無数にありますが、lazysizes は

  • 単体で動作する
  • script のサイズが小さい
  • <img>タグ以外のリソースにも遅延読み込みを適用できる方法を用意してくれている

という特徴があります。なかでも最後の特徴が非常に便利で、様々な応用が効きます。この記事では一番手軽な使い方といくつかの応用例を紹介します。

ベーシックな使い方

lazysizes のページにそのまま書いてある使い方です。

自分のページに配置したものや CDN にある lazysizes をスクリプトタグで読み込んだ上で、

<script src="lazysizes.min.js" async=""></script>

img タグのsrcを代わりにdata-srcにし、class にlazyloadを含めます。

<img data-src="image.jpg" class="lazyload" />

これだけで、画像が遅延読み込みになります。

また、下記のように一時的な画像(解像度が粗いがサイズの小さい画像など)を src 属性で指定しておくと、遅延読み込みが完了するまでの間その画像を表示してくれます。

<img src="tmp.png" data-src="image.jpg" class="lazyload" />

iframe 要素 や div 要素も、lazyloadクラスを付与することで遅延読み込みされるようになります。

css の background-image に対して遅延読み込み

ベーシックな使い方では img タグの画像が遅延読み込みになりましたが、css の background-image で指定した画像はどうでしょうか? これは CSS API を用いて実現できます。

lazysizes によって遅延読み込み対象になった html 要素は、はじめはlazyloadクラスを持っています。そして遅延読み込みが完了すると、lazyloadクラスがなくなり、代わりにlazyloadedクラスが付与されます。これを css セレクタで利用します。

例えば、元々以下のように background-image が指定されていたとします。

<div class="sugoi_haikei"></div>
.sugoi_haikei {
  padding: 0;
  background-image: url(../img/haikei.png);
}

以下のように、 div 要素が読み込まれた後のみ background-image を適用すれば、背景画像が遅延読み込みになります。

<div class="sugoi_haikei lazyload"></div>
.sugoi_haikei {
  padding: 0;
}

.sugoi_haikei.lazyloaded {
  background-image: url(../img/haikei.png);
}

script の遅延読み込み

script タグは、img や iframe のように、html タグを少し変えるだけで lazyload にはできません。画像のようにそれが必要になるタイミングが分からないためです。

しかし、JS API - Events を使えば、遅延読み込みの対象となった要素の読み込みが完了する直前のタイミングを検知できます。このタイミングで script タグを追加すれば、script の遅延読み込みが可能です。

例えば、以下のような div タグがユーザーのブラウザ上でアクティブになった瞬間に、ある script を読み込みたいとします。

<div id="hikigane"></div>

まずは、lazyloadedクラスを付けます。

<div id="hikigane" class="lazyload"></div>

そうすると、lazybeforeunveilイベントを使って、読み込みが行われるタイミングに何かしらを実行させることができます。ここでページに script を追加します。

document.addEventListener("lazybeforeunveil", function(e) {
  // イベントを発生させた要素がscriptタグを遅延読み込みしたい要素なら
  if (e.target.id === "hikigane") {
    var tag = document.createElement("script")
    tag.src = "totemo_sugoi.js"
    var head = document.getElementsByTagName("head")[0]
    head.parentNode.appendChild(tag)
  }
})

このようにして、処理が重い js などの読み込みタイミングを操作することができます。