Domain 62 / 225

lazy-loading は Googlebot がスクロール連動方式のみサポートする

lazy-loading の要点

lazy-loading は画像 / 動画 / iframe を必要時に読み込む高速化手法で Core Web Vitals 改善に貢献する。Googlebot は スクロール連動 lazy-load のみ対応し、ユーザーのクリック / タップを必要とする lazy-load は無視する。HTML の loading=lazy 属性または IntersectionObserver で実装

なぜこれを学ぶか

lazy-loading は Core Web Vitals 改善 + ページ速度向上の主要手段だが、誤った実装で主要コンテンツが Googlebot に拾われない事故が多発。

メディア・EC・大規模サイトで、画像 / 動画を多く扱うページの実装で必須の知識。

学ばないと起きること

よくある事故被害
クリック / タップで初めて画像読み込みGooglebot が拾わない、画像検索に出ない
主要コンテンツを「もっと見る」ボタン後の lazy-loadコンテンツがインデックスされない
native lazy-loading(loading="lazy")を全画像に適用LCP(Largest Contentful Paint)の主要画像も遅延、CWV 悪化
ATF(above the fold)画像を lazy-loadLCP 悪化
古い JS ライブラリで lazy-load 実装Googlebot が認識できない場合あり

学ぶメリット

  • Core Web Vitals 改善の安全な lazy-load 実装ができる
  • Googlebot が認識する方式 / 認識しない方式を区別できる
  • 商談で「クリック要求 lazy-load は SEO 対象外」を即答できる

仕組み

Googlebot が対応する lazy-load

公式: 「スクロール連動 lazy-load」のみ対応

方式Googlebot 対応
HTML loading="lazy" 属性対応
IntersectionObserver でスクロール検知対応
ユーザーのクリック / タップで読み込み非対応
ユーザーのスワイプで読み込み非対応
display: none の中に隠してクリックで表示非対応

HTML native lazy-loading

<img src="image.jpg" loading="lazy" alt="...">
<iframe src="..." loading="lazy"></iframe>

最もシンプル + Googlebot が確実に認識。

IntersectionObserver 実装

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));

JS で柔軟に実装できる。Googlebot もスクロール連動として認識。

キー概念

LCP との関係

LCP(Largest Contentful Paint)対象の画像(ATF のヒーロー画像など)は lazy-load しない

<!-- ヒーロー画像: lazy-load NG -->
<img src="hero.jpg" alt="..." fetchpriority="high">

<!-- スクロール先の画像: lazy-load OK -->
<img src="content.jpg" loading="lazy" alt="...">

ヒーロー画像を lazy-load すると LCP が遅延し、Core Web Vitals が悪化。

fetchpriority 属性

主要画像は優先取得:

<img src="hero.jpg" alt="..." fetchpriority="high">

ATF の主要画像に指定すると Googlebot も最優先で取得。

NG パターン: ユーザーアクション要求

<!-- NG: クリックで初めて読み込み -->
<button onclick="loadImages()">画像を表示</button>
<script>
function loadImages() {
  document.querySelectorAll('img[data-src]').forEach(img => {
    img.src = img.dataset.src;
  });
}
</script>

Googlebot はクリックしないため、画像が永久に読み込まれない → 画像検索 / コンテンツ判定の対象外。

iframe の lazy-loading

YouTube 埋め込みなどの iframe も同様:

<iframe src="https://www.youtube.com/embed/..." loading="lazy"></iframe>

ATF にない iframe(記事下のおすすめ動画など)は積極的に lazy-load 推奨。

構造化データとの整合

lazy-load した画像も構造化データの image プロパティに正しく URL を渡す:

{
  "@type": "Article",
  "image": [
    "https://example.com/hero.jpg",
    "https://example.com/sub-1.jpg",
    "https://example.com/sub-2.jpg"
  ]
}

実際の HTML で lazy-load されていても OK。Googlebot がレンダリング後に取得できれば問題なし。

よくある誤解

よくある誤解実際のところ出典
lazy-load した画像は SEO 上不利スクロール連動なら問題なしlazy-loading のベスト プラクティス
全画像に loading="lazy" を付けるのが推奨ATF のヒーロー画像は LCP 悪化の原因、付けない同上
クリック / スワイプで画像を読み込ませる lazy-load も Google 対応非対応、コンテンツが認識されない同上
iframe は lazy-load 対象外iframe も loading="lazy" 対応同上
native lazy-loading は対応ブラウザが少ない主要モダンブラウザはすべて対応、Googlebot も認識同上
構造化データの image プロパティと HTML が完全一致必須レンダリング後に取得できれば OK、lazy-load された URL でも問題なし構造化データ品質ガイドライン
IntersectionObserver より native lazy-loading の方が確実どちらも Googlebot が認識、IntersectionObserver は柔軟lazy-loading
lazy-load したコンテンツは alt テキスト不要alt テキストは画像 SEO で必須、lazy-load の有無に関係ないGoogle 画像 SEO

実務での適用

EC サイトの実装パターン

<!-- 商品メイン画像(LCP 対象)-->
<img src="product-main.jpg" alt="..." fetchpriority="high">

<!-- 商品サブ画像(lazy-load OK)-->
<img src="product-detail-1.jpg" loading="lazy" alt="...">
<img src="product-detail-2.jpg" loading="lazy" alt="...">

<!-- 関連商品(さらに下、lazy-load)-->
<div class="related-products">
  <img src="related-1.jpg" loading="lazy" alt="...">
  <img src="related-2.jpg" loading="lazy" alt="...">
</div>

Next.js の Image コンポーネント

import Image from "next/image";

// LCP 対象(ヒーロー / メイン画像)
<Image src="/hero.jpg" alt="..." width={1200} height={630} priority />

// 通常画像(lazy-load 自動)
<Image src="/content.jpg" alt="..." width={800} height={450} />

next/image は自動的に lazy-loading + WebP 変換 + サイズ最適化。

YouTube iframe の lazy-load

<iframe
  src="https://www.youtube.com/embed/..."
  title="..."
  loading="lazy"
  allowfullscreen
></iframe>

または Lite YouTube Embed のようなプレースホルダー戦略も有効。

トラブル別の対処

症状確認すべきこと
画像が画像検索に出ないクリック / タップで読み込む lazy-load になっていないか
LCP が悪化ヒーロー画像に loading="lazy" を付けていないか
構造化データの画像が認識されないURL が正しく渡されているか、レンダリング後に取得可能か
iframe が認識されないiframe の src が動的に挿入されているか、固定 src で実装

公式ソース

自己テスト

Q1. Googlebot が対応する lazy-load の方式は?

スクロール連動方式(HTML loading="lazy" / IntersectionObserver)。クリック / タップで読み込ませる方式は非対応

Q2. ATF のヒーロー画像に loading=lazy を付けるべきか?

NG。LCP(Largest Contentful Paint)が悪化する。ヒーロー画像は fetchpriority="high" で優先取得

Q3. クリックで初めて画像を読み込ませる lazy-load は SEO 上どうか?

Googlebot がクリックしないため画像が永久に読み込まれない。画像検索 / コンテンツ判定の対象外

Q4. iframe も loading=lazy 対応か?

対応。YouTube 埋め込みなど、ATF にない iframe は積極的に lazy-load 推奨

Q5. native lazy-loading と IntersectionObserver、どちらが推奨?

どちらも Googlebot が認識。シンプルなら native、柔軟性が必要なら IntersectionObserver

Q6. lazy-load した画像の構造化データ image プロパティはどう書く?

実際の URL を渡す。Googlebot はレンダリング後に取得するので、HTML で lazy-load されていても OK

Q7. lazy-load の alt テキストは省略できるか?

省略できない。alt テキストは画像 SEO で必須、lazy-load の有無に関係ない

Q8. Next.js で画像最適化するには?

next/image コンポーネントで自動 lazy-loading + WebP 変換 + サイズ最適化。LCP 対象は priority 属性

これらの内容を採点付きで挑戦したい場合は、本ドメインのプロ試験で 5 問形式で確認できる。