炭火Blog

[WordPress 6.4]画像のdecoding loading fetchpriority属性の記述

Blogging
/

※このページにはプロモーションが含まれています。

Table of Contents

WordPressのバージョンが5.5でthe_content()で出力されるimgタグにloading=”lazy”がつくようになり、5.9で最初に読み込むimgタグだけにloading=”lazy”が無くなりました。

WordPress 6.4の状態が正しい状態なのは、バグなのか調べてもはわからなかったのですが、画像にloading=”lazy”の記述が消えていました。その代わりにすべての画像にdecodind=”async”が、1枚目の画像にfetchpriority=”high”の記述があります。

今回考えるのはPageSpeed Insightでより良いスコアを出すための記述についてです。ただし、実際のページ表示を犠牲にしたり検索ボットにページの内容を隠したりしてしまうと、検索結果順位が下がりページを訪れる人が減るので、そうはならないように画像の読み込み方法を考えます。

decoding=”async” loading=”lazy”について

imgタグにdecoding=”async”が付くと、その画像は非同期で読み込まれます。帯域に十分に余裕がある場合、その画像は同時に読み込まれることで、全体の読み込み速度が上がります。

loading=”lazy”はファーストビュー以外の画像はページがスクロールされ、表示領域に入る寸前で読み込まれます。ファーストビュー領域に入っている画像にloading=”lazy”がある場合は、遅延読み込みされませんが同期的に読み込まれます。(同時に読み込まれません。)

decoding=”async”は同時に読み込めますが全部を読み込みます。loading=”lazy”はファーストビュー以外の画像は読み込まれません。

decoding=”async” とloading=”lazy”が同時にimgタグに含まれる場合はloading=”lazy”が優先されるようです。

decoding=”async”は同時に読み込まれるのだから、画像がいくらあってもページの読み込み速度が上がるかというと、そうでない場合があります。帯域が十分にない場合は非同期で読み込まれなくくなります。スマートフォンで3G回線を使った場合などでは非同期の読み込み数に上限があると考えて良いでしょう。

loading=”lazy”はページの下部にある画像は読み込まれないので、確実にページの読み込み速度が上がります。

fetchpriority=”high”について

fetchpriority=”high”は他の画像に対して読み込みの優先度を高めます。decoding=”async”と併用することで優先的に、非同期で読み込まれます。

fetchpriority=”high” decoding=”async”を消して全てにloading=”lazy”をつける

当ブログはアイキャッチ画像は設定しているものの、ページのトップには表示させていません。

ファーストビュー(アクセスの最初に表示される領域)に画像が無いのならページに含まれるすべての画像を遅延読み込みすることで、ファーストビューの表示速度を早めようと考えたのが次の2つのコードです。(不採用)

//fetchpriority="high" decoding="async"の無効化
function disable_loading_optimization_attributes( $loading_attrs ) {
    unset( $loading_attrs['fetchpriority'] );
    unset( $loading_attrs['decoding'] );
    return $loading_attrs;
}
add_filter(
    'wp_get_loading_optimization_attributes',
    'disable_loading_optimization_attributes'
);

Image loading optimization enhancements in 6.4(Make WordPress Core)で紹介されているコードにdecoding属性を非表示させるコードを追加したものです。

//すべてのimgタグにloading="lazy"を追加する。
function add_loading_lazy($the_content) {
    $the_content = preg_replace('/<img/', '<img loading=lazy', $the_content);
    return $the_content;
    }
add_filter('the_content','add_loading_lazy')

fetchpriority=”high” decoding=”async”を消して全てにloading=”lazy”をつけることはできたのですが、問題が2つあり、1つはファーストビューの範囲は思っていたより広いこと、2つ目はloading=”lazy”がついた画像がファーストビューに含まれる場合、画像は同期的に読み込まれるので読み込み速度がかなり遅くなることです。

ファーストビューとは最初に見える領域だとだけ漠然と考えていたのですが、実際にどの高さまでをファーストビューとして読み込むかはブラウザによって違うらしいことがわかりました。

ブラウザによってはページのトップから2000ピクセルまでをファーストビューとしている物もあるらしいです。

loading=”lazy”がついている画像がファーストビューに含まれるとブラウザに判断された場合は、他の要素が非同期で読み込まれた後に単独で読み込まれることで、読み込み速度を遅くします。

速いときもあるがかなり遅くなることもある、そして可能性は遅くなる方が高い。それならば1番目の画像は非同期で必ず読み込ませ、2番目以降は遅延読み込みさせようとしたのが次のコードです。

fetchpriority=”high” decoding=”async”はそのままに2番目からloading=”lazy”をつける

2番め以降の画像にloading=”lazy”をつけるコードが次のものです。

//fetchpriority="high"を含まないimgタグにloading="lazy"を追加する。
function add_lazy_loading_to_images($content) {
    // コンテンツ内のすべてのimgタグに対して処理
    $content = preg_replace_callback(
        '/<img(.*?)>/i',
        function ($match) {
            $img_tag = $match[0];
            $attributes = $match[1];

            // imgタグの属性にfetchpriority="high"が含まれていない場合
            if (strpos($attributes, 'fetchpriority="high"') === false) {
                // fetchpriority="high"が含まない場合にloading="lazy"を追加
                return '<img' . $attributes . ' loading=lazy>';
            }

            // fetchpriority="high"が含まれている場合はそのまま返す
            return $img_tag;
        },
        $content
    );

    return $content;
}

// the_contentフィルターに関数を追加(優先度を12に設定)
add_filter('the_content', 'add_lazy_loading_to_images', 12);

ブログ内リンクをショートコードで画像つきで出力する場合

バグがないかページを確認していると、当ブログの他の投稿を紹介するリンクの画像にもloading=”lazy”がついていました。

この紹介リンクはページのどの位置に挿入しているのかが分からないものです。そこでdecoding=”async”をつけて、ファーストビュー内に含まれる場合に非同期で読み込ませようとしていました。

fetchpriority=”high”がついていない場合にのみloading=”lazy”を付加するコードですから、紹介リンクの画像にもloading=”lazy”がついてしまいます。

そこで紹介リンクの画像にはfetchpriority=”auto”を新たに付け加えます。具体的には第3引数に配列を使います。

$thumb = get_the_post_thumbnail($id, 'thumbnail', array('decoding' => 'async','fetchpriority' => 'auto'));

そして、2番め以降の画像にloading=”lazy”をつけるコードの11行目を変更して、imgタグの属性にfetchpriority=”high”またはfetchpriority=”auto”が含まれていない場合にloading=”lazy”を追加するように変更します。

if (strpos($attributes, 'fetchpriority="high"') === false && strpos($attributes, 'fetchpriority="auto"') === false) {

これで紹介リンクの画像にloading=”lazy”は付加されなくなります。

今後WordPressのバージョンアップがあった時はloading=”lazy”がどうなっているのかを確認しようと思います。恐らくバグでloading=”lazy”が消えていると思われるので、その場合は今回のコードを消す必要があります。

最後までお読みくださり、誠にありがとうございます。

Amazon.co.jp
WordPressユーザーのためのPHP入門はじめから、ていねいに。[第3版]
Amazon.co.jp
WordPressオリジナルテーマ制作入門

関連投稿

週間アクセスランキング

このブログを書いている人

管理者 ほんだ

数多くあるブログの中で、このページをお読みくださりありがとうございます。このブログは、炭火で美味しいものを作ることを中心に、日々の趣味についてを文章にすることで、WordPressを使ってのWebページ作成を忘れないようにしています。熱帯魚の世話や野菜の栽培、Linuxについて興味のあることを、つたない文章で綴っています。兵庫県在住です。