WordPress 6.4以降では記述の仕方次第でget_header()があるとthe_content()で出力されるimgタグにloading="lazy"が付与されない
WordPress 5.5以降では、imgタグにloading="lazy"
が自動的に付与されるようになりました。
しかしWordPress 6.4以降では、記述次第でget_header()
があるとthe_content()
で出力されるimgタグにloading="lazy"
が付与されない事があります。この記事では、たまたま出会った表題の件について調査した結果をまとめます。
表題の再現
以下のようなコードを書いて、WordPress 6.4以降の環境で確認してみます。
<?php/** * @since 1.0.0 * @package test-theme */
?>
<!DOCTYPE html><html lang="ja"> <head> <?php wp_head(); ?> </head>
<body> <main> <?php get_header(); // NOTE: ここの有無でloading属性が付与されたり・されなかったりする the_content(); ?> </main> <?php wp_footer(); ?> </body></html>
get_header()
がある時と、コメントアウトした時で、imgタグにloading="lazy"
が付与されたり・されなかったりする様子が確認できます。
<figure class="wp-block-gallery has-nested-images columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"> <figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="640" data-id="5" src="http://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-1024x640.jpg" alt="" class="wp-image-5" srcset="https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-1024x640.jpg 1024w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-300x188.jpg 300w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-768x480.jpg 768w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-1536x960.jpg 1536w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-2048x1280.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img decoding="async" width="1024" height="576" data-id="6" src="http://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-1024x576.jpg" alt="" class="wp-image-6" srcset="https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-1024x576.jpg 1024w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-300x169.jpg 300w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-768x432.jpg 768w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-1536x864.jpg 1536w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-2048x1152.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img decoding="async" width="1024" height="640" data-id="7" src="http://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-1024x640.jpg" alt="" class="wp-image-7" srcset="https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-1024x640.jpg 1024w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-300x187.jpg 300w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-768x480.jpg 768w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-1536x960.jpg 1536w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-2048x1280.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img decoding="async" width="1024" height="640" data-id="8" src="http://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-1024x640.jpg" alt="" class="wp-image-8" srcset="https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-1024x640.jpg 1024w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-300x187.jpg 300w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-768x480.jpg 768w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-1536x960.jpg 1536w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-2048x1280.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img decoding="async" width="1024" height="640" data-id="9" src="http://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-1024x640.jpg" alt="" class="wp-image-9" srcset="https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-1024x640.jpg 1024w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-300x188.jpg 300w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-768x480.jpg 768w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-1536x960.jpg 1536w, https://cuddly-spiral.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-2048x1280.jpg 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></figure>
<figure class="wp-block-gallery has-nested-images columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"> <figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" data-id="5" src="http://panicky-mine.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-1024x640.jpg" alt="" class="wp-image-5" srcset="https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-1024x640.jpg 1024w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-300x188.jpg 300w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-768x480.jpg 768w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-1536x960.jpg 1536w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Antelope-Canyon-2048x1280.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" data-id="6" src="http://panicky-mine.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-1024x576.jpg" alt="" class="wp-image-6" srcset="https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-1024x576.jpg 1024w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-300x169.jpg 300w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-768x432.jpg 768w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-1536x864.jpg 1536w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Blue-Gradient-2048x1152.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" data-id="7" src="http://panicky-mine.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-1024x640.jpg" alt="" class="wp-image-7" srcset="https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-1024x640.jpg 1024w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-300x187.jpg 300w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-768x480.jpg 768w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-1536x960.jpg 1536w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Celestial-Night-Scene-2048x1280.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" data-id="8" src="http://panicky-mine.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-1024x640.jpg" alt="" class="wp-image-8" srcset="https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-1024x640.jpg 1024w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-300x187.jpg 300w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-768x480.jpg 768w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-1536x960.jpg 1536w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Colourwall-Variation-2048x1280.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure> <figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="640" data-id="9" src="http://panicky-mine.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-1024x640.jpg" alt="" class="wp-image-9" srcset="https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-1024x640.jpg 1024w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-300x188.jpg 300w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-768x480.jpg 768w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-1536x960.jpg 1536w, https://panicky-mine.localsite.io/wp-content/uploads/2025/03/Dancer-on-the-Stage-2048x1280.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></figure>
バージョン別の挙動の違いは以下の通りです。
WordPressバージョン | get_header()なし | get_header()あり |
---|---|---|
5.9.10 | lazyあり | lazyあり |
6.0.9 | lazyあり | lazyあり |
6.1.7 | lazyあり | lazyあり |
6.2.6 | lazyあり | lazyあり |
6.3.5 | lazyあり | lazyあり |
6.4.0 | lazyあり | lazyなし |
6.4.5 | lazyあり | lazyなし |
6.5.5 | lazyあり | lazyなし |
6.6.2 | lazyあり | lazyなし |
6.7.0 | lazyあり | lazyなし |
6.7.2 | lazyあり | lazyなし |
バージョン6.3.5まではget_header()
の有無に関わらずimgタグにloading="lazy"
が付与されていましたが、バージョン6.4.0以降はget_header()
があると付与されなくなることがわかります。
ちなみに以下のリポジトリにテーマ一式をアップしているので、より詳細を確認したい方は参照してみてください。
https://github.com/TsubasaHiga/wp-lazy-test-theme
調査
なぜget_header()
の有無でこの様な出力の違いが生じるのか疑問だったので、公式フォーラムにてトピックを立ててみました。(ヘッダーパーツの呼び出しをするとlazyが付与されないって一見謎ですよね)
imgタグにloading属性が付与される挙動について
すると、フォーラム内のユーザーより以下のような返信がありました。
manbo (@manbo) 1日、 3時間前
Image loading optimization enhancements in 6.4
お読みください。
仕様であればドキュメントを探していたのでこの情報は非常に有用でした。
get_header()
があるとlazyが付与されない理由
一言でいうと仕様だからです。
WordPress 6.4からは画像の遅延読み込みの最適化が行われており、以下のコンテキストにおいてはloading="lazy"
が付与されないようになりました。
- template_part_header
- get_header_image_tag
get_header()
のコンテキストはtemplate_part_header
です。
ヘッダーはファーストビューに存在する要素であることが多く、その中にある画像は当然スクロールせずに表示される画像の可能性が高いです。そのためWordPress側で自動的にloading="lazy"
を付与することが適切でないと判断するようになったということです。
要するに、ヘッダー内の画像はファーストビュー内にあることが多いので、loading="lazy"
は付与されないようになったということです。
でもthe_content()
で出力される画像にも影響したのはなぜ?
ヘッダー画像にloading="lazy"
が付与されないのは理解できますが、get_header()
があるとthe_content()
で出力される画像にも影響が出るのはなぜでしょうか?
それは今回再現に使用した以下のコードに原因があり、コンテキストの分離が適切に行われていないためです。
<?php get_header(); // NOTE: ここの有無でloading属性が付与されたり・されなかったりする the_content();?>
get_header()
はtemplate_part_header
のコンテキストで呼び出されますが、コンテキストの分離が最適に行われないままthe_content()
の呼び出しを行った為に意図しない副作用をもたらしたと考えられます。
本来ならthe_content()
のコンテキストはthe_content
であるべきですが、直前のtemplate_part_header
のコンテキストのまま画像の遅延読み込みの最適化が行われてしまい、ヘッダー画像と判断されloading="lazy"
が付与されなかったわけです。
このような問題は以下の記述の様にテンプレートパーツで読み込み、明確にコンテキストの分離を行うことで回避することができます。
<?php get_template_part('template-parts/header'); get_template_part('template-parts/content');?>
まとめ
- WordPress 6.4以降では、画像の遅延読み込みの最適化が行われており、
get_header()
で呼び出されるヘッダー要素内の画像にはloading="lazy"
が付与されない get_header()
のコンテキストはtemplate_part_header
であるため、適切にコンテキストの分離ができていない記述だとその後の処理にも影響が出る(今回だとthe_content()
)- コンテキストの分離を適切に行うことで、意図しない副作用を回避することができる
- コンテキストの分離はテンプレートパーツを使用するなどの方法がある
ちなみに画像の遅延読み込みの最適化処理はwp_get_loading_optimization_attributes()
でカスタマイズ可能
例えば投稿ページの画像にはloading="lazy"
の付与を強制する場合は、以下のような記述で実現できます。
/** * シングル投稿ページのコンテンツ内の画像にlazy属性を付与する * * この関数は以下のページタイプで動作します: * - デフォルトの投稿(post)の記事ページ * - カスタム投稿タイプの記事ページ * * @param array $loading_attrs 読み込み最適化属性の配列 * @param string $tag_name HTMLタグ名 * @param array $attr HTML属性の配列 * @param string $context コンテキスト * @return array 修正された読み込み最適化属性の配列 */function custom_loading_optimization_attributes($loading_attrs, $tag_name, $attr, $context) { // 画像タグ以外は早期リターン if ('img' !== $tag_name) { return $loading_attrs; }
// シングル投稿ページのコンテンツ以外は早期リターン if ('the_content' !== $context || !is_singular()) { return $loading_attrs; }
// ヘッダー画像は早期リターン if (isset($attr['class']) && strpos($attr['class'], 'header-image') !== false) { return $loading_attrs; }
// fetchpriority="high"が設定されている場合は早期リターン if (isset($loading_attrs['fetchpriority']) && $loading_attrs['fetchpriority'] === 'high') { return $loading_attrs; }
// 上記の条件に該当しない画像にlazy属性を付与 $loading_attrs['loading'] = 'lazy';
return $loading_attrs;}add_filter('wp_get_loading_optimization_attributes', 'custom_loading_optimization_attributes', 10, 4);