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-load | LCP 悪化 |
| 古い 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 問形式で確認できる。