SEOを考慮したGoogle推奨の画像の遅延読み込み処理まとめ FavoriteLoadingあとで読む

: 事務局
最近のGoogleのPageSpeed Insightsでは画像の遅延読み込みを推奨されますが、いまいち対応方法や情報がまとまっていなかったのでまとめました。WordPress向け対応も記載しています。

Googleはなぜページ表示速度を重視するのか?

そもそもなぜGoogleが、特にモバイルで画像の遅延読み込みを推奨しているかというと、世界中の回線環境の悪いユーザーを意識しているという理由が大きいと思われます。

そのような回線環境が悪いユーザーは、大きな画像をダウンロードすると、全然ページが表示されず、イライラします。ですから、グローバル展開しているGoogleとしてはモバイル向けの表示速度を無視できません。

実際GoogleのPageSpeed Insightsのアドバイスでも、特にモバイルで「画像の遅延読み込み」を推奨されます。

画像の遅延読み込みという対策

上記のような回線環境が悪いユーザーへの対策として。

まずファイルサイズの小さいダミー画像(下記のような画像)をダウンロードさせます。そうすれば、すぐにページが表示されるのでユーザーがイライラしなくてすみます。

しかしユーザーはダミー画像を見たいわけではないので、ユーザーがスクロールして該当の画像を見た時に、JavaScriptを用いて本当の画像を表示させる。

つまり画像を遅延読み込みさせることで、表示速度UPとユーザーの満足度UPを狙おうというのが「画像の遅延読み込み処理」になります。

画像の遅延読み込み処理を実現する方法

画像の遅延読み込みを実現するには、2つの対応が必要です。

  1. サイズの小さいダミー画像を用意する
  2. JavaScriptプログラムを用意する

1に関しては、サイズが小さければどんな画像でもよいです。

主に悩むのは2の部分でしょう。 まず、JavaScriptプログラムの用意の仕方は、だいたい以下のパターンにわかれるかと思います。

  • 自分で簡単なJavaScriptプログラムを書く
  • JSの画像遅延ライブラリを探して自分で書く
  • プログラムが組めないので、ネットでプログラムを探してコピペする
  • プログラムが組めないので、WordPressのPluginを使う

今回は、主に自分でプログラムを組む人に向けて情報を記載します。 WordPressも対象にして書きます。

プログラムが組めない人は、WordPressを使っているならPluginを使うのが最も良いと思います。

どのPluginがいいの?ということで悩まれると思いますが、「最新にメンテナンスされていそうなもの」がオススメです。なぜかというと、後述するのですが、Googleの推奨方式が時々かわるからです。

ライブラリは使わない方がよい!?実装方法の比較

JSのプログラムを組もうという人であれば、まず自分で1から書くより、ライブラリを探す人が多いと思います。

しかし、少しお待ちください。画像の遅延読み込みで実現したいのは下記ですよね。

  • 一番Googleに強い
  • ユーザーに対して一番早く軽く画像を表示できる
  • 実装(プログラム)が簡単

これらを考えると、ライブラリが唯一の選択肢ではありません。 以下、順番に。

Googleが推奨する画像遅延の手法はどれ?

Googleが推奨する方法は、ちゃんと公式ページに出ています。 こちらです。

イメージと動画の遅延読み込み -Developers Google

上記を読んでもらうとわかるのですが、GoogleはモダンブラウザでサポートされているIntersection Observerを使うことを推奨しています。 Intersection Observerは、まさに「要素が表示されたら」といった状態をコントロールするためのブラウザAPIで、画像の遅延読み込みに適しています。

普通に考えると、「ユーザーがスクロールしたら」ということで「スクロールイベント」を使ってしまいそうなのですが、GoogleはIntersection Observerの使用を推奨しています。

まぁGoogleのクローラーはユーザーではないので、スクロールして画像をちゃんと取得するというのはちょっと辛いですよね。だからこそ最近、公式サイトでGoogleクローラーはIntersection Observerを読み込めるようになった、とアナウンスするわけです。
※今後変わる可能性はありますので、上記リンク先は一度みておいてください。

JSの画像遅延ライブラリの比較

Googleの推奨を考慮するならば、ほとんどのJSのライブラリは、スクロールイベントを監視しているため、危険です。 有名なLazyLoadでもGoogleが認識できないことがあると指摘されています。私もスクロールイベントを使って少し影響があったサイトを知っています。

Lazy LoadはSEOに不向き? Lazy Loadで表示する画像をGooglebotは認識できないことがある -海外SEO情報ブログ

ある程度メンテナンスが入るライブラリであれば、そのうちIntersection Observerを採用するかも知れませんが、やはり未来は誰にもわかりません。

従って、私の推奨は「Intersection Observerを採用し、自分でJavaScriptを組む」ということです。

そもそも、とても簡単なんです。

自分で画像遅延を実装する方法

画像の遅延表示はなんら難しい処理ではありません。下記の順番で処理するだけです。

  1. 全てのimgタグを変更する。srcにダミー画像を指定し、data-src属性などに本当の画像を指定する。また処理対象にするために任意のclass名をつける
  2. JavaScriptで、各imgタグを監視する(ここにIntersection Observerを使う)
  3. 2.で表示されたら、data-src属性をsrc属性と入れ替えて本当の画像を表示させる

Gogole公式サイトにもコードサンプルあるのですが、ちょっとエラー処理が緩いので、実働するコードのサンプルを貼っておきます。

1の対応

imgタグを下記のようにします。 dummy.jpgがダミー画像。realimage.jpgが本当に表示したい画像です。

<img src="dummy.jpg" data-src="/img/realimage.jpg" class="lazy">

2と3の対応をするJavaScriptをいれる

下記のスクリプトを<head>の中に書くだけです。

<script>
document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          if (typeof lazyImage.dataset.srcset === "undefined") {
          }else{
              lazyImage.srcset = lazyImage.dataset.srcset;
          }
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to a more compatible method here
  }
});
</script>

問題点とその対処

画像の遅延処理自体は簡単なのですが、2つの問題点があります。

IntersectionObserverのサポート外ブラウザの対応と、WordPressの問題です。

IntersectionObserverサポート外のブラウザ対応

IntersectionObserverは比較的新しいブラウザでしかサポートされていないAPIです。従って、古いブラウザのために対策を考えなくてはいけません。

※先ほどのコードにもifのelse条件に”Possibly fall back to a more compatible method here”と記載があります。

一番簡単なのは「polyfill(ポリフィル)」を活用することです。

polyfill(ポリフィル)とは?

polyfillとは、「サポート対象外のブラウザ用に、自分で同等機能を供給する方法」のことです。 polyfillとは、海外にある「壁の隙間を埋めるペースト」の商品名(Polyfillaというらしい)から来た造語だそうで。

つまりIntersectionObserverのサポート対象外のブラウザでも、IntersectionObserverが使えるようなライブラリを、有志が作ってくれているのですね。 「polyfillを活用しよう!」という場合、そのライブラリを活用しよう、という意味になります。

ライブラリは下記からダウンロードできます。 github.com/w3c/IntersectionObserver/tree/master/polyfill

上記のpolyfillを活用する場合、冒頭に読み込みを一行いれて下記のようになります。

メリットはもちろん、そのライブラリを読み込めば、サポート対象外のブラウザであっても、普通にIntersectionObserverを使えるということです。

ポリフィルのライブラリを最初に読み込んだコードを下記に示します。パスはあたなの環境にあわせて書き換えてください。

<script src="/js/intersection-observer.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          if (typeof lazyImage.dataset.srcset === "undefined") {
          }else{
              lazyImage.srcset = lazyImage.dataset.srcset;
          }
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to a more compatible method here
  }
});
</script>

WordPressの問題

WordPressで画像遅延読み込みを実装しようとすると一つ問題が生じます。 それはimgタグが自動で吐き出されてしまうので簡単には置き換えられないという問題です。

  • WordPressでは画像挿入時に勝手にimgタグが作成されてしまう。
  • プラグインなどを入れると、それが勝手にimgタグを書き換える時がある

従って、上記問題を解決する必要があります。

※プログラムを避けたい人は、先ほどもお伝えしましたが「メンテナンスされている画像遅延系のプラグイン」を試してみるのがオススメです。

WrodPressの画像遅延の実装方法

今までもお伝えしましたが、画像の遅延読み込みをするためには、imgタグを書き換える必要があります。

WordPressでは下記3つを実行するとよいです

  • header.phpなどに、上記で示したJavaScriptプログラムを貼り付ける
  • テンプレートでimgを読み込んでいる箇所を変更する(これは簡単)
  • functions.phpにimgタグの変更プログラムを登録しておく

各imgタグは下記のように変更します。

<img src="dummy.jpg" data-src="/img/realimage.jpg" class="lazy">

dummy.jpgがダミー画像。realimage.jpgが本当に表示したい画像です。

functions.php内preg_replace(正規表現)でimgタグを置換する

WordPressが自動的に書き出す<img>タグを置換するには、functions.php内で処理を登録します。下記3つの手順で置換を順番に行えば、求めているimgタグに置換できます。

  • classの中にはlazyを必ず入れる(遅延読み込み対象にする目印)
  • classを持っていないimgタグにはclass=”lazy”を付与する
  • srcとdata-src、srcsetとdata-srcsetを入れ替えてセットし、src、srcsetにはダミー画像を指定する

functions.phpに登録する内容

functions.phpに記述すると、contentsの中身の置換処理などを行えます。 以下にfunction.phpに掲載するコードサンプルを出しますので、ぜひ参考にしてみてください。

※dummy.jpgはご自身で用意したものに書き換えてください。

function customize_img_lazy($content) {
  //classにlazyを付与
  $re_content = preg_replace('/(<img.*class=")/', '$1lazy ', $content);

  //classがないimgタグにもclass="lazy"を付与
  $re_content = preg_replace('/(<img*(?!.*class)[^>]*)/', '$1 class="lazy"', $re_content);

  //srcを入れ替え
  $re_content = preg_replace('/(<img[^>]*)\s+src=/', '$1 src="/img/dummy.jpg" data-src=', $re_content);

  //srcsetを入れ替え
  $re_content = str_replace('srcset','srcset="/img/dummy.jpg" data-srcset',$re_content);

  //置換したcontentsを返す
  return $re_content;
}
add_filter('the_content','customize_img_lazy');

上記では、正規表現を使っています。 一般的にうまくいくように記述していますが、場合によっては、あなたの環境ではうまく動かないかも知れません。

事前に正規表現チェックサイトなどを使って、置換がうまくいくかチェックされると良いと思います。

okumocchi.jp/php/re.php

まとめ

本日は、画像の遅延読み込みについてご説明しました。ライブラリを使わなくても、自分で簡単に実装できますし、そちらの方がGoogleから評価もされやすくなりますので、ぜひチャレンジしてみてください。

事務局
この記事を書いた人: 事務局

「ムダな情報で頭脳を消耗することなく考える時間を確保する」
ウェブのノウハウだけに限らず、広告やマーケティング全般の知識、時には組織論や時事に至るまで、最先端や未来予測などみなさんにとって本当に必要な情報だけをお届けします。