2026年5月20日
2026年5月20日
WordPressのLazy Load(遅延読み込み)を設定する方法
はじめに
Lazy Load(遅延読み込み)はビューポート外の画像やiframeを、ユーザーがスクロールして表示領域に近づいたタイミングで読み込む技術です。WordPress 5.5以降はネイティブの loading="lazy" が自動付与されますが、LCP画像には fetchpriority="high" を設定して優先読み込みが必要です。
症状・原因
- ページの初期読み込みが遅い
- PageSpeed Insightsで「スクリーン外の画像を遅延読み込みする」を指摘される
- ファーストビュー以外の画像も一括で読み込まれている
- LCP(最大コンテンツフルペイント)の対象画像の表示が遅い
解決手順
ステップ1:WordPress標準のLazy Loadを確認する
// WordPress 5.5以降はデフォルトでloading="lazy"が付与される
// wp_get_attachment_image() の出力例:
// <img src="image.jpg" loading="lazy" ...>
// デフォルト動作の確認
// 最初の画像にはloading="eager"が付与される(WP6.3以降)
// 最初の3画像はeager、それ以降はlazy
// 全画像にlazyを強制したい場合(非推奨)
add_filter('wp_lazy_loading_enabled', '__return_true');
ステップ2:LCP画像にfetchpriority=”high”を設定する
// functions.php
// ヒーロー画像(LCP対象)を優先読み込みに設定
function mytheme_hero_image_priority(string $html, int $attachment_id, string $size): string {
// ヒーロー画像のIDを指定(またはACF等で動的に取得)
$hero_image_id = get_theme_mod('hero_image_id');
if ((int) $attachment_id !== (int) $hero_image_id) {
return $html;
}
// loading="lazy" を削除し、fetchpriority="high"・loading="eager" を追加
$html = str_replace(' loading="lazy"', '', $html);
$html = str_replace('<img ', '<img fetchpriority="high" loading="eager" decoding="sync" ', $html);
return $html;
}
add_filter('wp_get_attachment_image', 'mytheme_hero_image_priority', 10, 3);
// アイキャッチ画像をLCPとして優先読み込み(シングルページ)
function mytheme_singular_thumbnail_priority(string $html): string {
if (!is_singular()) {
return $html;
}
static $first_thumbnail = true;
if (!$first_thumbnail) {
return $html;
}
$first_thumbnail = false;
$html = str_replace(' loading="lazy"', ' loading="eager"', $html);
$html = str_replace('<img ', '<img fetchpriority="high" ', $html);
return $html;
}
add_filter('post_thumbnail_html', 'mytheme_singular_thumbnail_priority');
ステップ3:iframeの遅延読み込みを設定する
// functions.php
// コンテンツ内のiframeにloading="lazy"を自動付与
function mytheme_lazy_load_iframes(string $content): string {
if (!is_singular()) {
return $content;
}
// YouTubeやGoogleマップなどのiframeに遅延読み込みを追加
$content = preg_replace(
'/<iframe(?![^>]*\bloading\b)([^>]*)>/i',
'<iframe loading="lazy"$1>',
$content
);
return $content;
}
add_filter('the_content', 'mytheme_lazy_load_iframes');
ステップ4:Intersection Observer APIでカスタムLazy Loadを実装する
// functions.php
function mytheme_enqueue_lazy_load_script(): void {
wp_add_inline_script('jquery', mytheme_get_lazy_load_js());
}
add_action('wp_footer', 'mytheme_enqueue_lazy_load_script');
function mytheme_get_lazy_load_js(): string {
return <<<'JS'
(function() {
// data-src 属性を持つ要素をLazy Loadする
const lazyImages = document.querySelectorAll('img[data-src]');
if (!lazyImages.length) return;
const observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (!entry.isIntersecting) return;
const img = entry.target;
img.src = img.dataset.src;
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
}
img.removeAttribute('data-src');
observer.unobserve(img);
});
}, { rootMargin: '200px 0px' }); // 200px手前で読み込み開始
lazyImages.forEach(function(img) { observer.observe(img); });
})();
JS;
}
// テンプレートでdata-src属性を使ったLazy Load画像出力
function mytheme_lazy_image(int $attachment_id, string $size = 'large'): string {
$src = wp_get_attachment_image_url($attachment_id, $size);
$srcset = wp_get_attachment_image_srcset($attachment_id, $size);
$alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
return sprintf(
'<img data-src="%s" data-srcset="%s" alt="%s" class="lazy" width="%s" height="%s">',
esc_url($src),
esc_attr($srcset ?: ''),
esc_attr($alt),
'800',
'600'
);
}
ステップ5:動画のLazy Loadを設定する
<!-- 動画のpreload属性をnoneに設定(自動バッファリングを防ぐ) -->
<video
src="video.mp4"
preload="none"
poster="thumbnail.jpg"
loading="lazy"
controls>
</video>
<!-- YouTubeはfacade(軽量サムネイル)で代替 -->
<!-- lite-youtube-embed ライブラリを使用 -->
<lite-youtube videoid="dQw4w9WgXcQ"></lite-youtube>
注意事項
- LCP対象の画像(ファーストビューのメイン画像)には絶対に
loading="lazy"を使わないでください。LCPスコアが悪化します fetchpriority="high"はページ内に1つだけにするのが理想です。複数設定すると優先度の意味がなくなります- Intersection Observer は古いブラウザ(IE)では動作しません。
loading="lazy"の方がブラウザサポートが広いため、こちらを優先してください
まとめ
WordPress 5.5以降の loading="lazy" は自動付与されるので追加設定は不要です。重要なのはLCP画像に fetchpriority="high" と loading="eager" を設定すること。the_content フィルターでiframeに loading="lazy" を付与し、カスタムコンポーネントには Intersection Observer でビューポート近傍での読み込みを実装します。