遅延ロードした画像をGoogleにインデックスさせる方法

#遅延ロードは画像SEOに向かない？
[鈴木 謙一さんのブログ](https://www.suzukikenichi.com/blog/lazy-load-might-be-bad-for-seo/)によると「Lazy Load（遅延ロード）」された画像はGooglebotに認識されない可能性がある、とのこと。

[Lazy LoadはSEOに不向き？ Lazy Loadで表示する画像をGooglebotは認識できないことがある | 海外SEO情報ブログ]
(https://www.suzukikenichi.com/blog/lazy-load-might-be-bad-for-seo/)

#画像の遅延ロードとは
よくある遅延ロードは、透過PNGなどのダミー画像やローディング画像などを画像パスに設定します。そしてユーザーが画像のある位置までスクロールして初めて画像が読み込まれます。jQueryのプラグインなどでも多くの種類がありますが、やっていることは概ね変わりません。

```html
<img src="img/dummy.png" data-original="img/01.png" alt="" width="800" height="100" class="lazy">
```

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="js/jquery.lazyload.min.js"></script>
<script>jQuery(function($){$("img.lazy").lazyload();});</script>
```

- 「dummy.png」は1px×1pxの透過PNGとします。
- ここでは「class="lazy"」が付いた画像にのみ遅延ロード。

それでは既にGoogleにインデックスされている画像を使って検証をしてみます。

#実際に検証してみる
##Google画像検索（施策前）
![検索結果・前.jpg](https://qiita-image-store.s3.amazonaws.com/0/95865/ce49b3ba-b734-5654-f390-adaaff72a062.jpeg)

施策（遅延ロード）前はこんな感じで、ページに使われている画像がほぼインデックスされている状態です（比較的短いページのため数はそう多くは無い）。
ここに、ページ内の全ての画像に遅延ロードするよう施策してみましょう。
インデックス促進のため「Search Console」にて「Fetch as Google」を行います。
案の定、ファーストビューに収まらなそうな画像はリソースが読み込まれません。

![Search-Console.png](https://qiita-image-store.s3.amazonaws.com/0/95865/faad7031-fc9c-820b-06b5-a1a33b9543cd.png)

半日ほど経つと下記のように反映されました。

##Google画像検索（通常の遅延ロード施策後）
![検索結果・中.jpg](https://qiita-image-store.s3.amazonaws.com/0/95865/297e249e-b072-95ec-94ae-d6e1865a5b49.jpeg)

左上の画像はこのページに設定されたOGP画像で、真ん中・右の画像はファーストビューに入っている画像のため、遅延ロードされない画像となります。

確かに、**遅延ロードを適用することでインデックスされた画像が減ってしまっている**ことが分かります。これに対して何か対策はできるのでしょうか？

#いろいろやってみる
##1. ダミー画像の指定不要な遅延ロード「Qazy.js」。しかし…
画像SEOを考慮して作られた遅延ロードとのことで試してみましたが、実際に開発者ツールで見てみると**画像がダウンロードされてしまっている**ことが分かります。作者が言うには50マイクロ秒後に画像パスを書き換えるため「サイズの大きい画像であれば」ダウンロードはキャンセルされる、とのこと。これではあまり意味がありませんので、使えないかと思います。

[qnimate/Qazy · GitHub]
(https://github.com/qnimate/Qazy)

##2. Mobifyの仕組みを見てみる
「Mobify」はGoogleのマルチスクリーンベンダーとして推奨されており、花王株式会社やスターバックスのサイトも採用しています。サイトをマルチデバイス用に最適化配信してくれるサービスです。

[PCサイトをスマホに対応・最適化｜Mobify（モビファイ）]
(http://www.domore.co.jp/mobify/)

仕組みを調べてみると、&lt;head&gt;タグ付近で&lt;plaintext style="display:none"&gt;をdocument.writeしていることが分かります。
閉じタグが無いため&lt;plaintext&gt;タグはそこより下のソースをテキストと解釈します。そこでHTMLソースを最適なものに書き換え、これを出力しているのですが、それでもソース上部にあるPC用画像はダウンロードされてしまっています。&lt;plaintext&gt;タグ発行の前に画像がある程度ダウンロードされてしまうのでしょう。

**&lt;plaintext&gt;タグを発行して画像パスを書き換えて遅延ロードに…と考えましたがどうやら無理**のようです。

[FAQフォーラム - Mobifyはどのようにしてリソースの読み込みを防いでいるのですか？]
(http://support.domobi.jp/content/7/147/ja/mobify%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E3%81%97%E3%81%A6%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%82%92%E9%98%B2%E3%81%84%E3%81%A7%E3%81%84%E3%82%8B%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F.html)

##3. リンクを含む画像
```html
<a href="img/02.png"><img src="img/dummy.png" data-original="img/02.png" alt="" width="800" height="100" class="lazy" /></a>
```
一般的なブログでも、画像をクリックするとより大きい画像が表示されるというケースは多々あります。リンク先の画像をGooglebotがインデックスし、検索結果に表示されているものと思われます。しかし、**画像に何でもかんでもリンクというのはためらわれ**ます。

##4. &lt;noscript&gt;内にパスを設定した画像
```html
<noscript><img src="img/03.png" alt="" width="800" height="100" /></noscript>
<img src="img/dummy.png" data-original="img/03.png" alt="" width="800" height="100" class="lazy" />
```
&lt;noscript&gt;内に遅延ロードを設定していない通常の&lt;img&gt;タグを記しています。これでも一応はインデックスされるようですが、Googleのジョン・ミューラー曰く**&lt;noscript&gt;の使用は推奨しない**とのこと。何でも、Googlebotは&lt;noscript&gt;タグ内のソースを完全に正しいものとは信用しないからだとか？感覚的にもあまり使いたくないタグですね。

#「Googlebotに対しても機能する別のLazy Load」とは何か？
ところで、先の鈴木 謙一さんの記事で示された解決法、Googleのジョン・ミューラーが語った**「Googlebotに対しても機能する別のLazy Loadに変更する」とは何でしょうか？**
画像をGooglebotに認識させつつ、遅延ロードも出来るJavaScriptなんて本当にあるのでしょうか？

**「Googlebotがアクセスした場合のみ画像パスを変更しない」**ような遅延ロードが出来れば、これが実現できそうです。

HTML側は何もせず、Googlebot以外であれば

- class="lazy"を付加
- 画像パスにダミー画像を指定
- 値を画像パスにしたdata-original属性を設定
- 遅延ロードのJavaScriptを設置

ということをPHPでやってみましょう。

画像の遅延ロードを考慮していない普通のHTMLです。

```html
<img src="img/01.png" alt="" width="800" height="100">
```

HTMLのスクレイピング及びソース書き換えを「phpQuery」という便利なライブラリで行います。使い勝手の良いシロモノです。

[【phpQuery】で簡単WEBスクレイピング！をしてみた。 | 株式会社パーソンリンク]
(http://person-link.co.jp/web/964)

```php
<?php
// phpQueryの読み込み
require_once("phpQuery-onefile.php");

// テンプレートHTMLファイルの指定
$file = "./templates/index.html";

// HTMLの取得
$html = file_get_contents($file);

$phpQuery = phpQuery::newDocument($html);

// Googlebot判定
$is_gbot = strpos($_SERVER["HTTP_USER_AGENT"], "Googlebot");

// Googlebot以外のみ画像パスを置き換え、遅延ロードを設置
if ($is_gbot === false) {

	foreach ($phpQuery->find('img') as $img){
		// 画像パスを取得
		$src = $img->getAttribute('src');

		// class="lazy"を付加
		pq($img)->addClass('lazy');

		// 値を画像パスにしたdata-original属性を設定
		$img->setAttribute('data-original', $src);

		// 画像パスにbase64形式のダミー画像を設定
		$img->setAttribute('src', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAAXNSR0IArs4c6QAAAANQTFRFAAAAp3o92gAAAAF0Uk5TAEDm2GYAAAABYktHRACIBR1IAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==');
	}

// 遅延ロードのJavaScript
$script = <<< EOF

	<script src="js/jquery.lazyload.min.js"></script>
	<script>
	jQuery(function($) {
		$("img.lazy").lazyload();
	});
	</script>

EOF;

	$phpQuery->find('body')->append(pq($script));
}

// HTMLの出力
print phpQuery::getDocument();
?>
```

##Google画像検索（PHPテンプレート後）
![検索結果・後.jpg](https://qiita-image-store.s3.amazonaws.com/0/95865/c6842041-776f-903c-f7ea-c01f6ce2bf93.jpeg)

半日後、見事にインデックスされた画像が戻りました。まあ画像パスに正しい画像を指定しているのですから当然ではあるかもしれません。

もしWordPressをお使いであれば下記の記事が参考になるでしょう。

[wordpressでLazy Load系pluginをGooglebot に認識させる方法 | CreativeTips]
(http://11neko.com/lazy-load-seo/)

#参考

[グーグルのJavaScript理解はまだ発展途上。画像の遅延読み込みは少し注意 | 海外&国内SEO情報ウォッチ | Web担当者Forum]
(http://web-tan.forum.impressrd.jp/e/2014/05/30/17567/page/1)

[google search - Lazy loading images and effects on SEO - Webmasters Stack Exchange]
(http://webmasters.stackexchange.com/questions/61761/lazy-loading-images-and-effects-on-seo)