そもそもなぜGoogleが、特にモバイルで画像の遅延読み込みを推奨しているかというと、世界中の回線環境の悪いユーザーを意識しているという理由が大きいと思われます。
そのような回線環境が悪いユーザーは、大きな画像をダウンロードすると、全然ページが表示されず、イライラします。ですから、グローバル展開しているGoogleとしてはモバイル向けの表示速度を無視できません。
実際GoogleのPageSpeed Insightsのアドバイスでも、特にモバイルで「画像の遅延読み込み」を推奨されます。
上記のような回線環境が悪いユーザーへの対策として。
まずファイルサイズの小さいダミー画像(下記のような画像)をダウンロードさせます。そうすれば、すぐにページが表示されるのでユーザーがイライラしなくてすみます。
しかしユーザーはダミー画像を見たいわけではないので、ユーザーがスクロールして該当の画像を見た時に、JavaScriptを用いて本当の画像を表示させる。
つまり画像を遅延読み込みさせることで、表示速度UPとユーザーの満足度UPを狙おうというのが「画像の遅延読み込み処理」になります。
画像の遅延読み込みを実現するには、2つの対応が必要です。
1に関しては、サイズが小さければどんな画像でもよいです。
主に悩むのは2の部分でしょう。 まず、JavaScriptプログラムの用意の仕方は、だいたい以下のパターンにわかれるかと思います。
今回は、主に自分でプログラムを組む人に向けて情報を記載します。 WordPressも対象にして書きます。
プログラムが組めない人は、WordPressを使っているならPluginを使うのが最も良いと思います。
どのPluginがいいの?ということで悩まれると思いますが、「最新にメンテナンスされていそうなもの」がオススメです。なぜかというと、後述するのですが、Googleの推奨方式が時々かわるからです。
最新のおすすめプラグインはこちら
→Web運用本の著者にも聞いた!WordPressサイトで絶対導入すべきおすすめプラグイン3選と注意するポイント【2021年版】
JSのプログラムを組もうという人であれば、まず自分で1から書くより、ライブラリを探す人が多いと思います。
しかし、少しお待ちください。画像の遅延読み込みで実現したいのは下記ですよね。
これらを考えると、ライブラリが唯一の選択肢ではありません。 以下、順番に。
Googleが推奨する方法は、ちゃんと公式ページに出ています。 こちらです。
イメージと動画の遅延読み込み -Developers Google
上記を読んでもらうとわかるのですが、GoogleはモダンブラウザでサポートされているIntersection Observerを使うことを推奨しています。 Intersection Observerは、まさに「要素が表示されたら」といった状態をコントロールするためのブラウザAPIで、画像の遅延読み込みに適しています。
普通に考えると、「ユーザーがスクロールしたら」ということで「スクロールイベント」を使ってしまいそうなのですが、GoogleはIntersection Observerの使用を推奨しています。
まぁGoogleのクローラーはユーザーではないので、スクロールして画像をちゃんと取得するというのはちょっと辛いですよね。だからこそ最近、公式サイトでGoogleクローラーはIntersection Observerを読み込めるようになった、とアナウンスするわけです。
※今後変わる可能性はありますので、上記リンク先は一度みておいてください。
Googleの推奨を考慮するならば、ほとんどのJSのライブラリは、スクロールイベントを監視しているため、危険です。 有名なLazyLoadでもGoogleが認識できないことがあると指摘されています。私もスクロールイベントを使って少し影響があったサイトを知っています。
Lazy LoadはSEOに不向き? Lazy Loadで表示する画像をGooglebotは認識できないことがある -海外SEO情報ブログ
ある程度メンテナンスが入るライブラリであれば、そのうちIntersection Observerを採用するかも知れませんが、やはり未来は誰にもわかりません。
従って、私の推奨は「Intersection Observerを採用し、自分でJavaScriptを組む」ということです。
そもそも、とても簡単なんです。
画像の遅延表示はなんら難しい処理ではありません。下記の順番で処理するだけです。
Gogole公式サイトにもコードサンプルあるのですが、ちょっとエラー処理が緩いので、実働するコードのサンプルを貼っておきます。
imgタグを下記のようにします。 dummy.jpgがダミー画像。realimage.jpgが本当に表示したい画像です。
<img src="dummy.jpg" data-src="/img/realimage.jpg" class="lazy">
下記のスクリプトを<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は比較的新しいブラウザでしかサポートされていないAPIです。従って、古いブラウザのために対策を考えなくてはいけません。
※先ほどのコードにもifのelse条件に”Possibly fall back to a more compatible method here”と記載があります。
一番簡単なのは「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で画像遅延読み込みを実装しようとすると一つ問題が生じます。 それはimgタグが自動で吐き出されてしまうので簡単には置き換えられないという問題です。
従って、上記問題を解決する必要があります。
※プログラムを避けたい人は、先ほどもお伝えしましたが「メンテナンスされている画像遅延系のプラグイン」を試してみるのがオススメです。
今までもお伝えしましたが、画像の遅延読み込みをするためには、imgタグを書き換える必要があります。
WordPressでは下記3つを実行するとよいです
各imgタグは下記のように変更します。
<img src="dummy.jpg" data-src="/img/realimage.jpg" class="lazy">
dummy.jpgがダミー画像。realimage.jpgが本当に表示したい画像です。
WordPressが自動的に書き出す<img>タグを置換するには、functions.php内で処理を登録します。下記3つの手順で置換を順番に行えば、求めているimgタグに置換できます。
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');
上記では、正規表現を使っています。 一般的にうまくいくように記述していますが、場合によっては、あなたの環境ではうまく動かないかも知れません。
事前に正規表現チェックサイトなどを使って、置換がうまくいくかチェックされると良いと思います。
本日は、画像の遅延読み込みについてご説明しました。ライブラリを使わなくても、自分で簡単に実装できますし、そちらの方がGoogleから評価もされやすくなりますので、ぜひチャレンジしてみてください。