今まで画像遅延読み込みと言えば、プラグインやテーマの機能で対応するものだったけれど、これからはWordPressデフォルトで対応してくれるようになりました。
WordPressでも高速化は重要視され、どんどん開発が進んでいるようだね。
進むべき道は正しいと思うし、WordPress側で対応してくれるのはとてもありがたいんだけど、画像遅延読み込みはすでに実装済みの人は多いのでは?
それらを辞めて、WordPress5.5で実装された画像遅延読み込みを使うべきなのか、モロモロを考えてみたのでメモします☆
WordPress5.5で実装された画像遅延読み込みの仕組み
ネイティブレイジーロード(Native Lazy Loading)です。
大きな特徴としては、ブラウザ側で判断や処理をしてくれるということです。
画像遅延読み込みはJavascriptで行うものというのはもう昔の話で、最近はブラウザ側でサポートしてくれるんだね~。
今までもGoogle製の「Native Lazyload」っていうプラグインがあったみたい。
わたしは使ったことなかったけど(*´ω`*)
WordPressデフォルトで実装となると、これが今後のスタンダードになるのかな?
ネイティブレイジーロード(Native Lazy Loading)の実装方法
imgタグにloading属性を付与することでそれをブラウザが読み取り、画像遅延読み込みをしてくれます。
別途Javascriptは必要なしです。
なんというお手軽さ・・・。
WordPressでの設定方法
この画像遅延読み込みを使う方法だけど、管理画面から特に設定などは必要なさそうです。
WordPress5.5以上であれば、それだけで画像遅延読み込みが有効になります。
ただし、仕様としてimgタグにwidthとheightが必須です。
理由とかの詳しい説明はドキュメントを読もう。
WordPressのフィルター処理的にimgタグにwidthとheightがあるかを判別して、自動的に loading=”lazy” を付与することで、ネイティブレイジーロードが機能するという感じです。
注意点としてはフィルター処理なので、WordPress関数を使っていないハードコーディングされた画像には機能しません。
テーマやプラグイン作者さんは要チェックだね。
わたしの場合はプレースホルダー画像(No image)が該当したのでそこを修正しました。
ウィジェットの画像について
上のドキュメントにある通り、デフォルトでフィルターが通るのは以下です。
- the_content
- the_excerpt
- widget_text_content
- get_avatar
- wp_get_attachment_image
※wp_get_attachment_image について、 the_post_thumnail() とか the_custom_logo() とか画像を表示させる関数全般だと思っていればたぶんOKです。
そうです、カスタムhtmlのウィジェットで画像を表示させていると loading=”lazy” が付与されませんorz
imgタグで画像を表示させる場合は「テキストウィジェット」を使うようにしよう。
テーマやプラグインの画像遅延読み込みとの競合
恐らくだけど、重複したせいで画像が表示されない!とか、クリティカルなエラーはないと思います。
ただ処理効率としてはよろしくないので、いずれはどちらを採用するか精査した方がいいね。
っと言ってもテーマやプラグイン側で対応するだろうから、競合の問題は気にせず放置でも良さそう。
気になる場合はテーマ、プラグイン作者さんに聞いてみよう!
Intersection Observerを使った画像遅延読み込みじゃダメなの?
わたしの場合、自作テーマにてすでにIntersection Observerを使った画像遅延読み込みを実装していました。
これを辞めてネイティブレイジーロード(Native Lazy Loading)にした方がいいか考えたんだけど、結論としては
Intersection Observerも捨てたもんじゃない
ということです。
Googleが推進している以上、今後はネイティブレイジーロードがスタンダードになっていくのかなとは思いますが、Intersection Observerが使えなくなったわけではありません。
実際にネイティブレイジーロードとIntersection Observerを比較して検証してみたけど、わたしが導き出した結果はIntersection Observerの方が高機能ということでした。
Intersection Observerと一言で言っても、それを組み込む人によって画像遅延読みこの仕様が異なると思うのであくまでもわたしの場合の結論ということで。
ネイティブレイジーロードとIntersection Observerの比較メモ
どっちがいいのか考えるにあたって実際に試行錯誤した内容です。
いくつかあるのでメモしておきます。
Intersection Observerは「Loazd.js」を使っています。
ちなみに、WordPressデフォルトのネイティブレイジーロードはCLSの問題でwidth・heightのない画像には loading=”lazy” を付与しないみたいだけど、わたしが仕上げた画像遅延読み込みの仕様はwidth・heightがない場合は wp_get_attachment_image_src で取ってきて自動的に追加しています。
あとプレースホルダの大きさだけど、レスポンシブに表示している画像の場合でもCSSで指定しているので、CLSの問題は起きないようにしています。
挙動
▼ネイティブレイジーロード
▼Intersection Observer
比較すると、ネイティブレイジーロードの方が表示させる前の画像でも広範囲に読み込んでいます。
Intersection Observerは設定で画面外の画像がどれくらい近づいたら表示させるかを設定できますが、わたしは5%で指定しています。
また、ネイティブレイジーロードは画面外の画像であっても、ファーストビューと一緒に読み込んでいる画像も見受けられました。
関連記事のサムネイルなどの小さめの画像なのですが、この辺の遅延読み込みの判断はブラウザが勝手にしているようなので、こちらではその判断にゆだねるしかないのかなと思いました。
PageSpeed Insightsのスコア
▼ネイティブレイジーロード
▼Intersection Observer
Intersection Observerの方がPageSpeed Insightsのスコア的には優れていました。
Intersection Observerは設定次第ですが、厳格に画像遅延読み込みをしているからでしょう。
ネイティブレイジーロードも画面外の画像を読み込むタイミングをこちらで変更できるのであれば、スコアは改善できると思います。
実装難易度
▼ネイティブレイジーロードの実装手順
- imgタグにloading属性を付与する
▼Intersection Observerの実装手順
- imgタグにdata-src属性などを付与してsrc属性の画像は削除かダミーを用意する
- imgタグに識別するためのclass「loazd」などを付与する
- Javascriptを読み込む
ネイティブレイジーロードはimgタグに属性を追加するだけっていうのがとにかく楽チンです。
わたしもIntersection Observerより先にネイティブレイジーロードを知っていたら、簡単なネイティブレイジーロードで実装したと思います(笑
付け加えると、Intersection Observerはポリフィルにて未対応のブラウザにも対応できますが、ネイティブレイジーロードはブラウザが未対応なら遅延読み込みせずそのまま表示させるだけです。
Intersection Observerは未対応ブラウザを放置すると、画像は表示されないままなんだよね。
この辺を考えても、やはりネイティブレイジーロードはお手軽だな~と思います。
対応ブラウザ
Intersection Observerの方が広範囲で使えます。
ただネイティブレイジーロードは今後対応ブラウザは増える見込みです。
しかも、仮に未対応ブラウザで表示させても画像が表示されないといったことはないため、まだ画像遅延読み込みを実装していないサイトなら、とりあえずloading属性で対応させても損はないのかなと思いました。
結論
汎用性、実装難易度に優れたネイティブレイジーロード
画像遅延読み込みの機能(表示速度)を優先するならIntersection Observer
ネイティブレイジーロードはiframeにも対応しているが・・・
調べたところ、ネイティブレイジーロードはiframeに対応しているようですが、WordPressのデフォルトではiframeにloading属性は付与されません。
※バージョン5.5現在
付与する関数はあるのかな?
wp_filter_content_tags() が新たに使えるようになったってドキュメントにはあったけど、わたしにはよく分からなかったorz
とりあえず正規表現で置換すればiframeにもloading属性は付与できました。
function bnp_customize_native_lazy_iframe($content) {
if( is_admin() || bnp_amp_check() ) return $content;
$content = preg_replace('/<iframe([^>]+?)><\/iframe>/', '<iframe$1 loading="lazy"></iframe>', $content);
return $content;
}
add_filter('the_content','bnp_customize_native_lazy_iframe');
add_filter('comment_text','bnp_customize_native_lazy_iframe');
add_filter('widget_text','bnp_customize_native_lazy_iframe');
ただ、わたしの環境ではなぜかブログカードのiframeが機能しなくなり(;´Д`)
比較のところの動画でもブログカードが表示されていないのが分かります。
※後に回避したけど
対策として、ブログカードには「wp-embedded-content」というクラスが付いているので、これを除外するように、
$content = preg_replace('/<iframe(?!.*wp-embedded-content)([^>]+?)><\/iframe>/', '<iframe$1 loading="lazy"></iframe>', $content);
として回避しました。
これはテーマやプラグインの環境に依存するかもしれないので人によっては不要かも。。。
ネイティブレイジーロードはvideoタグに対応しているか
こんなことは言う必要が無いかも知れないけど一応。
そもそも、videoタグには preload という属性があり、これによって事前に読み込むか再生ボタンを押されてから読み込むかを指定できます。
なのでネイティブレイジーロードに限らず、videoタグについては遅延読み込みは別途意識しなくていいんじゃないかな?
デフォルトでついてきてしまう loading=”lazy” を削除するには?
以下のディスカッションが参考になりました。
https://wordpress.org/support/topic/how-to-disable-global-lazy-loading/
functions.phpなどに以下の一行を追加すればOKです。
add_filter( 'wp_lazy_loading_enabled', '__return_false' );
あとがき
Googleが推奨してるし、WordPressでもデフォルトで実装されたネイティブレイジーロード。
今後のスタンダードになっていくのは分かるけど、がんばって自作テーマに実装したIntersection Observerの画像遅延読み込みは愛着がある・・・。
機能的にもPageSpeed Insightsのスコアは良いし、まだ捨てるのは早いはず・・・。
ということで、自作テーマでは選べるようにしてみました。
このブログではどうしようか。
う~ん、、、
表示速度にはこだわっているので、Intersection Observerの画像遅延読み込みを採用することにします。