LP高速化のために5つの画像の遅延読み込みライブラリを比較した

ベーシックアドベントカレンダー22日目です。
8日ぶり3回目の@tkhrです。
画像の遅延読み込みライブラリ比較の話です。

LPの高速化のために遅延読み込みを導入します。
対象になるLPは広告からの流入で表示するページになります。
なのでユーザの熱を冷まさせない工夫が必要ですね。
そのための工夫の一つとして今回は画像の遅延読み込みに対応します。
画像ならキャッシュがあるじゃん。と言えるかもしれませんが、広告LPなので初めてのユーザが大半なのでアテにできませんね。
なので遅延読み込みによってファーストビューが表示されるまでの時間を短縮することが狙いとなります。

## 遅延読み込みとは
ページにアクセスした時には画像の読み込みはせず、必要になった時に画像を読み込みます。
必要になった時というのは、その画像が表示される時ですね。
それによってページにアクセスした時の読み込み時間を短縮できるので、ユーザのイライラを軽減できそう！という算段です。

## 遅延読み込みの注意点
いいことばかりではなく、SEO的には不利かもしれないらしいです。
遅延読み込みの画像をGoogle botが画像を認識できないため、画像検索結果に乗ってこないようです。
ですが、検索順位に関してはマイナスの影響はないはずとのことです。
[Lazy LoadはSEOに不向き？ Lazy Loadで表示する画像をGooglebotは認識できないことがある | 海外SEO情報ブログ](https://www.suzukikenichi.com/blog/lazy-load-might-be-bad-for-seo/?utm_source=feedburner&utm_medium=twitter&utm_campaign=FeedBurner)
[Lazy LoadはSEOに不利 遅延ロードの画像が認識されない | いわしブログ](http://wind-mill.co.jp/iwashiblog/2015/09/lazy-load-seo/)

とはいえ、今回の場合は広告のLPなのでそこまで気にする必要はなさそうですね。
とはいえ、SEOを気にしなきゃいけないけど遅延読み込みしたいという場合の方法を紹介している記事もありました。
[遅延ロードした画像をGoogleにインデックスさせる方法 - Qiita](http://qiita.com/ryo_hisano/items/e8554777793551c105bd#googlebot%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E3%82%82%E6%A9%9F%E8%83%BD%E3%81%99%E3%82%8B%E5%88%A5%E3%81%AElazy-load%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B)
とはいえ、検索結果にどれだけ影響を与えるのか不明確な上、クローキングに当たってしまうかもしれないのでそこは要検討といったところでしょうか。
クローキングというのは人間とbotで表示するコンテンツを変えるということです。[クローキング - Search Console ヘルプ](https://support.google.com/webmasters/answer/66355?hl=ja)

## 遅延読み込みライブラリ比較
探してみると結構いろいろ出てきたので比較しました。
全て僕だけの主観です。

評価軸としては以下の通り
1. ライブラリの軽さ
  表示の高速化が目的なのでより軽いほうがいいですよね。
2. ガクガクしないか
  閲覧時に読み込みが走ってレイアウトがガクガクするのはストレスでしかないので閾値とかで読み込み開始を調整できるやつがいいですね
  そもそもimgで高さを指定しておけばいいのですが。。。
3. 対応ブラウザ
  古いIEにも対応しないといけないのです。

見つけたライブラリ群です。
- lazyload [Github](https://github.com/tuupola/jquery_lazyload) [DEMO](http://www.appelsiini.net/projects/lazyload/enabled.html)
- lazysizes [Github](https://github.com/aFarkas/lazysizes) [DEMO](http://afarkas.github.io/lazysizes/#examples)
- layzr.js [Github](https://github.com/callmecavs/layzr.js) [DEMO](http://callmecavs.com/layzr.js/)
- tada.js [Github](https://github.com/fallroot/tada)
- echo.js [Github](https://github.com/toddmotto/echo) [DEMO](https://toddmotto.com/labs/echo/)

### lazyload
遅延読み込みライブラリでググるととりあえずこれが出てきます。
定番というかデファクトスタンダードな印象です。
これはjQueryのライブラリとして提供されています。

1. ライブラリの軽さ：jQueryあるし重め
2. ガクガクしないか：調整可能
3. 対応ブラウザ：jQuery次第

#### 使い方
bower&npm対応してました。

```bash
bower install jquery.lazyload
npm install jquery-lazyload
```

jqueryを読んでからlazyloadを読む。
遅延読み込みする画像のimgタグのclassに `lazy`、data-originalに読み込む画像のパスを指定する。

```html:demo.html
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>
<!-- do something -->
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
```

```javascript:demo.js
$('img.lazy').lazyload({
  threshold: 200,    // 読み込み閾値 px
  effect: 'fadeIn',  // 読み込みエフェクトも指定できる
});
```

### lazysizes
「究極に軽量なレイジーローダー」とのこと。
jQuery無しで動いてくれます。
レスポンシブ対応やiframe、jsの遅延読み込みもできます。
プラグインで機能の拡張もできるので物足りない時に拡張しやすいと思います。
htmlのdata-*属性で細かい設定ができるので画像ごとに対応を変えたい時に便利そう。

1. ライブラリの軽さ：良
2. ガクガクしないか：調整可
3. 対応ブラウザ：全対応（ただしIE8以下は対応してない）

#### 使い方
bower&npm対応してます

```bash
bower install lazysizes
npm install lazysizes
```

対象のimgタグのclassに `lazyload` 、data-srcで画像パスを指定する。
このclassとdata-srcも設定で変更できます。
lazysizes自体は非同期で読めるのでいいですね。


```html:demo.html
<script src="lazysizes.js" type="text/javascript" async=""></script>
<!-- do something -->
<img data-src="image.jpg" class="lazyload" />
```

```javascript:demo.js
window.lazySizesConfig = window.lazySizesConfig || {};

// lazyloadに合わせるとこう
window.lazySizesConfig.lazyClass = 'lazy';
lazySizesConfig.srcAttr = 'data-original';

// 読み込みタイミングの調整
lazySizesConfig.loadMode = 1;
lazySizesConfig.expFactor = 3;
```


### layzr.js
「小さい、早い、モダン」
こちらもjQuery依存は無しです。
遅延読み込みと画質の指定ができます。

画質をnormalに加えてretinaで指定でき、さらにsrcsetでの指定もできます。
画質の高い画像がたくさんページだと遅延読み込みの恩恵を大きく得られそうですね。

1. ライブラリの軽さ：良
2. ガクガクしないか：調整可
3. 対応ブラウザ：モダンブラウザのみ（[詳細](https://github.com/callmecavs/layzr.js#browser-support)）


#### 使い方
npmとCDNがあります。

```bash
npm install layzr.js
```

```html:CDN
<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/layzr.js/2.0.2/layzr.min.js"></script>
<!-- cdnjs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/layzr.js/2.0.2/layzr.min.js"></script>
```

imgタグで画像のパスを指定します。
`data-normal`でデフォルトの画像を指定します。これは必須です。
`data-retina`で画質がいいやつを指定します。これはオプションになります。
`data-srcset`で `srcset` の指定をします。
これらの属性は設定で変更できます。


```html:demo.html
<script src="layzr" type="text/javascript" async=""></script>

<!-- readmeそのままですが -->
<!-- normalの指定が必須 -->
<img data-normal="normal.jpg">

<!-- 高画質をオプションで -->
<img data-normal="normal.jpg" data-retina="retina.jpg">

<!-- ブラウザがsrcsetに対応していればsrcsetで表示してくれる -->
<img data-normal="normal.jpg" data-srcset="small.jpg 320w, medium.jpg 768w, large.jpg 1024w">
```


``` javascript:demo.js
const layzr = Layzr({
  normal: 'data-original',  // data-*属性の指定ができる
  retina: 'data-high',
  threshold: 0  // 画像の読み込みタイミングをvhで指定します。正の値だと早く、負の値だと遅くなります。
});
```


### tada.js
「軽くて依存がない」
コミット数が9とまだ新しいライブラリのようです。
閾値をパーセントで指定できるのでレスポンシブ対応の時に便利そうです。
jQuery依存はないです。

あとimgタグ以外で背景画像として扱ってくれるのでいいですね。

1. ライブラリの軽さ：良
2. ガクガクしないか：調整可
3. 対応ブラウザ：メジャーブラウザ。IEは9以上

#### 使い方
インストールはリポジトリからダウンロードして使うしかないぽいです。
https://github.com/fallroot/tada

`data-src` 属性で画像ファイルを指定します。
imgタグで指定するとそのまま画像で扱ってくれて、
imgタグ以外のタグで指定すると、背景画像として扱ってくれます。

```html:demo.html
<script src="tada.js" type="text/javascript" async=""></script>

<img data-src="original.png">
<div data-src="background.png"></div>
```

```demo.js
Tada.setup({   // 必要に応じて設定を変える。デフォルトで問題なければ不要
  attribute: 'data-origin',  // 属性の指定
  threshold: '20%'           // pxでの指定もできます。
});

Tada.add('img');  // addメソッドで適用する。引数はCSSのセレクタが使える。
```


### echo.js
「サイズが小さくて早くてシンプル」
このライブラリも単体で動作します。
2KB以下のサイズなので本当に小さいですね。
しかもIE8以上で動作します。

1. ライブラリの軽さ：良
2. ガクガクしないか：調整可
3. 対応ブラウザ：メジャーブラウザ。IEは8以上

#### 使い方
bower&npmあります。

```bash
bower install echojs
npm install echo-js
```

imgタグに `data-echo` 属性を付けて指定します。
`data-echo-background` 属性で指定すると要素の背景にしてくれます。

```html:demo.html
<script src="echo.js" type="text/javascript" async=""></script>

<img src="blank.png" data-echo="original.png">
```

設定を変える場合は `init` メソッドでできます。
echo.jsに関しては属性の変更はできないみたいですね

```demo.js
echo.init({
  offset: 100  // px 画像読み込み開始のオフセット
});
```


## まとめ
5つ比べてみましたが、echo.jsを入れようかと思います。
対象がLPなので、クリックしたら表示するとか見た目の装飾は必要なく、ガクガクせず遅延読み込みができれば満足です。
単体でIE8対応かつ軽量なところが決まり手でしたね。

調べる前はデファクトっぽいlazyloadにしようかと思いましたが、echo.jsに心変わりしました。
遅延読み込みができればいいという視点でしたが、それを前提でより適したものを使うという視点で考えられました。
ライブラリの調査にちゃんと時間を割くというのも大事ですね。

遅延読み込みという単純なことのためのライブラリなので1つか2つに集約されているものだと思いましたが、意外と数があっておもしろかったです。
加えて付属で知識がついた（SEOやsrcsetなど）のでそれもまた収穫でした。