LCPリソースの読み込み遅延を最適化してください。
遅延から表示へ:Largest Contentful Paintのリソース読み込み遅延を改善する方法を学びます。
このガイドはLargest Contentful Paint (LCP)ハブの一部です。リソース読み込み遅延は、特にSPAサイトにおいて、LCPスコア悪化の最大の要因です。
LCPのリソース読み込み遅延を最適化する
Largest Contentful Paint (LCP) は、4つのLCPサブフェーズ(TTFB、リソース読み込み遅延、リソース読み込み時間、要素のレンダリング遅延)から構成されます。
ヒント:LCPが画像の場合、テキストよりもほぼ確実に遅くなります。RUMデータでLCP要素のタイプをトラッキングしてください。そうしなければ、手探り状態になります。
Table of Contents!
- LCPのリソース読み込み遅延を最適化する
- リソース読み込み遅延とは
- ブラウザはLCP要素をどのように検出するのか
- Core Web Vitalsにおいてリソース読み込み遅延が重要な理由
- リソース読み込み遅延の検出方法
- 一般的な原因と効果の高い解決策
- リソースヒントによる高度な優先順位付け
- <link rel="preload">による早期検出の強制
- fetchpriority="high"とブラウザの優先度キュー
- サードパーティ接続の最適化:preconnectとdns-prefetch
- 表:LCP最適化のためのリソースヒント比較
- 包括的で将来を見据えた戦略
- モダンなCDNの役割
- Speculation Rulesによる遅延の完全な排除
- ケーススタディの統合:理論から実践へ
- リソース読み込み遅延を改善する方法
- 次のステップ:LCPの最適化を続ける
リソース読み込み遅延とは
リソース読み込み遅延とは、TTFBからブラウザがLCPリソースのダウンロードを開始するまでの時間です。基本的に、ブラウザはLCPリソース(LCP画像など)をできるだけ早くキューに入れる必要があります。すぐにキューに入らない場合、ブラウザがリソースを直ちに検出できないか、重要性を認識していないことが主な原因です。
この値が大きい場合、初期HTMLのpayload内にリソースURLを見つけられないというアーキテクチャ上の問題を示しています。リソース読み込み遅延は、ブラウザがLCPリソースの必要性を特定し、取得を決定するまでに費やす時間と言えます。
また、リソース読み込み遅延はリソースが実際に読み込まれる前に発生するという点も重要です。そのため、レスポンシブ画像やWebP、AVIFなどの新しい画像フォーマットとは関係がありません。

システムフォントでレンダリングされるテキストベースのLCP要素の場合、外部リソースを取得する必要がないため、リソース読み込み遅延は通常ゼロです。値が大きくなるのは、画像や動画ファイルなどの外部ネットワークリソースに依存するLCP要素に限られます。
ブラウザはLCP要素をどのように検出するのか
リソース読み込み遅延を減らすには、ブラウザがリソース(またはLCP要素)を検出する仕組みを理解する必要があります。ブラウザは、高速なパスと低速なパスという2つのメカニズムを使用します。まず、LCP要素を「高速なパス」に乗せる必要があります。

- DOMパーサー(低速なパス):ブラウザのメインパーサーであり、非常に強力です。HTMLやCSSを読み込み、JavaScriptと対話してページ全体を構築します。他のファイルのダウンロードや実行によって遅延や停止が発生し、依存関係の連鎖が遅延を引き起こすため、これは低速なパスです。
- プリロードスキャナー(高速なパス):DOMパーサーは(相対的に)遅いため、ブラウザにはダウンロード可能なリソースを非常に高速でスキャンし、何にも停止されない超高速のセカンダリスキャナーがあります。<script>、lazy loadingではない<img>、または<link>タグを見つけると、CSSの解析やJavaScriptの実行よりも前に、直ちにダウンロードキューに入れます。これはすべての重要なリソースにとって最適なパスです。
リソース読み込み遅延を最適化する戦略全体は、1つの原則に基づいています。それは、LCPリソースのURLをプリロードスキャナーができるだけ早く検出できるようにすることです。
つまり、LCP要素については以下の2点を意味します。
loading="lazy"属性を持たない通常の画像タグを使用して、プリロードスキャナーが検出できるようにする。- プリロードスキャナーが重要度の低いリソースを優先しすぎないようにする。
Core Web Vitalsにおいてリソース読み込み遅延が重要な理由
経験の浅い開発者はLCPを「ファイルサイズ」の問題だと考えがちです。その結果、チームは画像圧縮、モダンな画像フォーマット、レスポンシブ画像に注力してしまいます。これは間違いです。独自のCore Web Vitals調査によると、LCPの最大のボトルネックはTTFB(48%)であり、次いでリソース読み込み遅延(24%)です。読み込み時間はわずか10%に過ぎず、レンダリング遅延が17%で続きます。

ここでのポイントは、TTFBは常に存在する一方で、リソース読み込み遅延はほぼ完全に修正可能だということです。したがって、リソース読み込み遅延は最も最適化のポテンシャルが高い要素となります。
リソース読み込み遅延の検出方法
リソース読み込み遅延を修正するには、まず正確に測定する必要があります。ワークフローは常に同じです。CrUXで確認し、実際のユーザーデータ(RUM)で問題を定義してから、Chrome DevToolsで詳細な分析を行います。
ステップ1:CrUXで確認する
CrUXは、条件を満たしたChromeユーザーから収集されたGoogleの公開field dataであり、Core Web Vitalsの75パーセンタイル値を28日間のローリングデータとして提供します。数値の良し悪しはわかりますが、誰が、何を、なぜ、といった理由はわかりません。GoogleはCrUXデータに依存しているため、出発点として最適な信頼できる情報源です。
cruxvis.withgoogle.comにアクセスしてウェブサイトを入力し、Loading Performanceに移動して、Largest Contentful Paint (LCP)のimage subpartsをクリックします。

ステップ2:field data(RUM)を分析する
RUMは、実際のすべてのユーザーからCore Web Vitalsを収集し、より具体的で詳細なビューを提供します。任意の切り口で「誰が」「何を」を教えてくれますが(この情報は非常に価値があります)、理由はわかりません。
このCoreDashのスクリーンショットは、どのURLでリソース読み込み遅延が発生しているか(緑色)を示しています。

ステップ3:DevToolsで診断する
RUMデータでターゲットページとLCP要素を特定したら、Chrome DevToolsを使用して原因を診断します。ここでの目的は、問題を再現し、LCPのサブパートを測定して、正確なリソース読み込み遅延の値を取得することです。また、DevToolsではmain threadの分析を行い、実行中のどのタスクがレンダリングプロセスをブロックしているかを正確に確認します。

ステップバイステップガイド:このワークフローの完全な解説を作成しました。Chrome DevToolsのPerformanceパネルでLCPを診断するをご覧ください。スロットリングの設定、トレースの記録、LCPの内訳インサイトから正確なリソース読み込み遅延の値を読み取る方法をカバーしています。
一般的な原因と効果の高い解決策
リソース読み込み遅延が大きい原因は、LCPリソースの検出が遅いか、fetch priorityが低く設定されているかのいずれかです。ここでは、最も一般的なアーキテクチャ上の間違いとその解決策を説明します。
原因:LCPがCSS経由で読み込まれている
問題:プリロードスキャナーはCSSファイルを解析しません。LCP画像がCSSのbackground-imageで定義されている場合、そのURLはこの高速スキャナーから見えません。ブラウザが画像を検出できるのは、HTMLをダウンロードし、CSSファイルのリンクを見つけ、CSSファイルをダウンロードし、CSSOMを構築し、スタイルを適用した後のみです。この依存関係の連鎖が、リソース読み込み遅延の直接的な原因になります。このパターンの詳細については、背景画像の遅延読み込みに関するガイドをご覧ください。
解決策:正しい実装は、重要なLCP要素にbackground-imageを使用しないことです。代わりに標準の<img>タグを使用してください。これにより、プリロードスキャナーがすぐに見つけられるHTML内に画像URLが直接配置されます。CSSを使用すれば、同じ視覚的結果を得ることができます。
実装例:
アンチパターン(避けるべき実装):
<!-- CSS -->
.hero {
background-image: url('hero-image.jpg');
height: 500px;
width: 100%;
}
<!-- HTML -->
<div class="hero"></div>
ベストプラクティス(推奨する実装):
<!-- HTML -->
<div class="hero-container">
<img
src="hero-image.jpg"
alt="A descriptive alt text for the hero image"
fetchpriority="high"
class="hero-background-img"
width="1200"
height="500"
/>
<div class="hero-content">
<h1>Page Title</h1>
</div>
</div>
<!-- CSS -->
.hero-container {
position: relative;
height: 500px;
width: 100%;
}
.hero-background-img {
position: absolute;
inset: 0; /* Equivalent to top: 0; right: 0; bottom: 0; left: 0; */
width: 100%;
height: 100%;
object-fit: cover; /* This property mimics background-size: cover */
z-index: -1; /* Places the image behind other content */
}
この実装は同じ視覚的結果をもたらしますが、LCP画像を可能な限り早い段階で検出できるようにし、読み込み遅延を最小限に抑えます。
原因:クライアントサイドレンダリングとJavaScriptのインジェクション
問題:ReactやVueなどのクライアントサイドレンダリング(CSR)フレームワークを使用するアプリケーションは、最小限のHTMLシェルのみを提供することがよくあります。LCPの<img>タグを含む実際のコンテンツは、大規模なフレームワークバンドルがダウンロード、解析、実行された後にのみ、JavaScriptによってDOMに挿入されます。このプロセスは根本的にLCPリソースをプリロードスキャナーから隠し、検出の大きな遅延を引き起こします。
解決策:最も効果的な解決策は、初期レンダリングをクライアントからサーバーに移すことです。
- サーバーサイドレンダリング(SSR)または静的サイト生成(SSG):SSRやSSGのようなアーキテクチャパターンは、サーバー上で完全なHTMLを生成します。ブラウザは<img>タグとそのsrc属性を含む完全なドキュメントを受け取るため、LCPリソースはプリロードスキャナーによって直ちに検出可能になります。これは、パフォーマンスが重要なすべてのページで必須となるアーキテクチャです。
- フレームワーク固有の最適化:モダンなフレームワークは組み込みの最適化も提供しています。例えば、Next.jsの<Image>コンポーネントにはpriorityプロパティがあります。これをtrueに設定すると、フレームワークは自動的に適切な<link rel="preload">とfetchpriority="high"属性を追加し、画像が検出され、適切な優先度で取得されることを保証します。
原因:LCP画像でのloading="lazy"の使用
問題:これは頻繁に発生し、影響の大きい間違いです。loading="lazy"属性は、viewportに近づくまで画像の取得を遅らせるようブラウザに直接指示するものです。これはファーストビューより下にある画像には適切な最適化ですが、ファーストビューのLCP要素に適用するのは逆効果です。ブラウザのプリロードスキャナーはloading="lazy"を持つ画像を無視するように設計されており、検出の遅れと大きなリソース読み込み遅延が確実になります。
解決策:解決には継続的な管理が必要です。
- LCP画像からloading="lazy"を削除する:LCP要素になる可能性のある画像には、決して
loading="lazy"属性をつけてはいけません。ブラウザのデフォルトの動作はloading="eager"であり、これは重要なファーストビューコンテンツに適切な設定です。loading属性を完全に省略しても同じ効果があります。 - サードパーティツールの監査と構成:サードパーティツールも監査する必要があります。WordPressのような多くのCMSプラットフォームや各種画像最適化プラグインは、すべての画像に自動的にlazy loadingを適用します。LCP画像をこの動作から除外するように、これらのツールを構成することが不可欠です。これには通常、ページ内の最初の1つまたは2つの画像に対して除外ルールを作成する作業が伴います。
原因:最適ではないHTML構造と大きなドキュメント
問題:プリロードスキャナーはHTMLドキュメントを上から下へ処理します。ヘッダーのアイコンやチャットウィジェットのスクリプトのような、重要ではないが帯域幅を消費するリソースが、LCP要素よりも<body>内の上部に配置されていると、それらが先に見つかってダウンロードキューに入れられます。これにより初期のネットワーク帯域幅が消費され、LCPリソースのダウンロードが遅れる可能性があります。HTMLドキュメントが大きいことも問題になります。LCP要素がブラウザの受け取る最初のデータチャンク(約14KB)に含まれていない場合、その検出は少なくとも1ネットワークラウンドトリップ分遅れます。
解決策:HTML内のコンテンツの構造と優先順位を最適化してください。
- HTMLの順序を入れ替える:可能な限り、LCP要素の<img>タグやテキストブロックを、<body>タグ内の最も早い位置に配置してください。
- 重要でない画像の優先度を下げる:HTMLソースの早い段階に表示する必要がある必須ではない画像(ヘッダーのアイコンなど)には、
loading="lazy"を適用します。これにより、プリロードスキャナーはそれらをスキップし、LCP要素のためにダウンロードキューを確保します。 - 必須ではないスクプレットを遅延させる:分析、広告、ソーシャルメディアウィジェットのスクリプトが初期レンダリングに不可欠であることは稀です。それらの
<script>タグを<body>の最後に移動するか、defer属性を使用してください。これにより、それらがパーサーをブロックしたり、LCPリソースとネットワーク帯域幅を競合したりするのを防ぎます。
リソースヒントによる高度な優先順位付け
LCPリソースがHTML内で検出可能になったら、リソースヒントを使用して、取得方法に関するより明確な指示をブラウザに与えることができます。これらのヒントは、検出と優先順位付けをきめ細かく制御します。
<link rel="preload">による早期検出の強制
<link rel="preload">はヒントではなく、ディレクティブです。メインパーサーがまだ検出できない場合でも、高い優先度でリソースをダウンロードするようブラウザに強制します。これをHTMLの<head>に配置することは、フォント、CSSのbackground-image、またはDOMの深い場所にあるLCP画像などのリソースにおいて、検出の遅れを修正する最も直接的な方法です。実装の詳細と例については、LCP画像のプリロード方法に関する専用ガイドをご覧ください。
メカニズム
HTMLドキュメントの<head>にpreloadリンクが配置されると、プリロードスキャナーはそれを識別し、直ちに指定されたリソースをダウンロードキューに入れます。これは、外部スタイルシートで@font-faceを介して読み込まれるフォント、CSSのbackground-imageによるLCP(ただし<img>タグの使用が推奨されます)、または複雑なDOM構造の深い場所にあるLCP画像などのリソースに最適です。
レスポンシブなプリロード
レスポンシブ画像をプリロードする場合は、重要な実装の細部に注意が必要です。ブラウザがユーザーのviewportに合わせて正しいサイズの画像をプリロードし、無駄な二重ダウンロードを避けるためには、<link rel="preload">タグに、対応する<img>タグの属性を完全に反映したimagesrcsetとimagesizes属性を含める必要があります。
レスポンシブなプリロードの例:
<link rel="preload" as="image"
href="lcp-image-large.jpg"
imagesrcset="lcp-image-small.jpg 400w, lcp-image-medium.jpg 800w, lcp-image-large.jpg 1200w"
imagesizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
fetchpriority="high">
<img src="lcp-image-large.jpg"
srcset="lcp-image-small.jpg 400w, lcp-image-medium.jpg 800w, lcp-image-large.jpg 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
alt="A descriptive alt text"
fetchpriority="high"
width="1200" height="675">
潜在的な落とし穴
プリロードは取得タイミング(リソース読み込み遅延とリソース読み込み時間)を解決しますが、描画タイミングは解決しません。プリロードされた画像が到着したときに、重いJavaScriptやrender blocking CSSによってmain threadがブロックされている場合、画像は描画されるまで待機しなければなりません。これにより、ボトルネックがリソース読み込み遅延から要素のレンダリング遅延へと移る可能性があります。
fetchpriority="high"とブラウザの優先度キュー
fetchpriority属性は、リソースのダウンロードにおける相対的な重要性を示すヒントです。これにより、ブラウザのダウンロードキュー内でのリソースの優先度に影響を与えることができます。
ブラウザの優先順位付けの仕組み
ページ読み込み中にブラウザがリソースを検出すると、それぞれに内部的な優先度レベルを割り当てます。デフォルトでは、viewport内の画像は「低(Low)」の優先度から始まり、ブラウザがレイアウトを完了してそれらが可視であると判断した後に「高(High)」にアップグレードされます。このアップグレードには、ブラウザが先にCSSをダウンロードして解析する必要があるため、遅延が生じます。fetchpriority="high"属性は、検出された瞬間から画像の優先度を「高(High)」に設定することで、このプロセスを完全にバイパスします。優先度アップグレードによる遅延がなくなるため、LCP画像にとっては特に効果的です。
preloadとfetchpriorityの違い
これら2つのヒントは、目的は異なりますが相互に補完し合います。preloadは、リソースがいつ検出されてキューに追加されるかに影響します。fetchpriorityは、キューに入った後の優先度レベルに影響します。この違いを理解することは重要です。preloadは遅い検出を解決し、fetchpriorityは低い優先順位付けを解決します。HTML内にすでに存在する多くのLCP画像では、fetchpriorityだけで十分な場合があります。これらの相互作用の完全なガイドについては、リソースの優先順位付けの記事をご覧ください。
LCPのベストプラクティス
LCP画像の場合、最適な戦略は両方を一緒に使用することです。まず、<img>タグをHTMLの早い段階に配置するか、preloadを使用して早期検出を確実にします。次に、fetchpriority="high"を<img>タグ(および使用している場合はpreloadリンク)に直接追加します。この組み合わせにより、リソースが早期に検出されるだけでなく、スタイルシートやフォントなどの他のリソースとのネットワーク帯域幅の競争に勝つための最高優先度が与えられます。
例:
<img src="lcp-image.jpg" fetchpriority="high" alt="A critical hero image">
fetchpriority="low"を使用するタイミング
fetchpriority属性は、優先度を上げるためだけのものではありません。fetchpriority="low"を使用して、LCP画像と帯域幅を競合する重要でないリソースの優先度を下げることもできます。一般的な候補としては、LCP要素ではないファーストビューの画像(ヘッダーの小さなアイコンやアバターなど)や、必要ではあるが緊急ではないプリロードされたリソースなどが挙げられます。これらの競合するリソースの優先度を明示的に下げることで、LCP画像のための帯域幅の余裕を生み出すことができます。
<!-- LCP image: high priority -->
<img src="hero.jpg" fetchpriority="high" alt="Hero image" width="1200" height="600">
<!-- Non-critical above-fold image: low priority -->
<img src="avatar.jpg" fetchpriority="low" alt="Author avatar" width="48" height="48"> 実証された効果
Googleフライトの事例では、LCPの背景画像にfetchpriority="high"を追加することで、LCPスコアが2.6秒から1.9秒に改善され、700msの大幅な短縮を達成しました。
サードパーティ接続の最適化:preconnectとdns-prefetch
問題
LCPリソースが画像CDNやGoogle Fontsのようなフォントプロバイダーなどのサードパーティドメインでホストされている場合、ブラウザはそのドメインへの新しいネットワーク接続を確立する必要があります。このプロセスには、DNSルックアップ、TCPハンドシェイク、TLSネゴシエーションが含まれ、リソースの最初のバイトがダウンロードされる前にこれらすべてを完了しなければなりません。この接続セットアップ時間は、クロスオリジン資産のリソース読み込み遅延の直接的な要因となります。
解決策
preconnect:このヒントは、指定されたサードパーティオリジンのための完全な接続セットアップ(DNS、TCP、TLS)を、バックグラウンドで事前に行うようブラウザに指示します。実際にリソースがリクエストされたときにはすでに接続が確立されているため、セットアップの遅延が解消されます。これは非常に効果的であり、LCPリソースを提供する最も重要な1つまたは2つのサードパーティドメインに対して推奨されます。dns-prefetch:これはドメインのDNSルックアップのみを実行する軽量なヒントです。preconnectよりも短縮できる時間は少ないですが、ブラウザのサポートが広く、fallbackとして、あるいは重要度の低いサードパーティドメインに役立ちます。
実装のベストプラクティス
最大限の互換性を確保するために、両方のヒントを提供してください。ブラウザはサポートされていればpreconnectを使用し、そうでなければdns-prefetchにfallbackします。フォントのようなCORSを使用して取得されるリソースには、crossorigin属性が不可欠です。
<link rel="preconnect" href="https://my-image-cdn.com" crossorigin>
<link rel="dns-prefetch" href="https://my-image-cdn.com">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 表:LCP最適化のためのリソースヒント比較
これらの強力なヒントの誤用を防ぎ、それぞれの役割を明確にするため、以下の表に比較のまとめを示します。
| Hint | Type | Primary Purpose | Impact on LCP Load Delay | Best Use Case for LCP |
|---|---|---|---|---|
preload | ディレクティブ | 特定のリソースの早期取得を強制する | 検出が遅れたリソースの検出遅延を直接的に解消する | 検出が遅れたLCP画像(CSSのbackground-imageなど)やフォント。 |
fetchpriority | ヒント | 検出されたリソースのダウンロード優先度を通知する | 他のアセットよりも優先度を上げ、キューの待機遅延を減らす | LCPの<img>タグ自体に使用し、重要でないリソースよりも先にダウンロードさせる。 |
preconnect | ヒント | ドメインへの完全なネットワーク接続を事前に確立する | クロスオリジンの接続セットアップ時間(DNS、TCP、TLS)を解消する | LCP画像やフォントをホストする重要なサードパーティドメイン。 |
dns-prefetch | ヒント | ドメインのDNSルックアップのみを事前に実行する | クロスオリジンの接続時間のうち、DNSルックアップ部分を短縮する | preconnectのfallback、または重要度の低いサードパーティドメイン。 |
包括的で将来を見据えた戦略
リソースヒントだけでなく、より広範なアーキテクチャの決定により、リソース読み込み遅延をさらに削減できます。
モダンなCDNの役割
Content Delivery Network (CDN) はWebパフォーマンスの基盤技術であり、特にLCPリソースにおいて、間接的ではあるもののリソース読み込み遅延を大幅に削減します。
- 接続オーバーヘッドの削減:サーバーのグローバルネットワーク全体にアセットを分散することで、CDNはユーザーの地理的により近い場所にコンテンツを配置します。これにより、接続セットアップ時間の構成要素であるDNSルックアップ、TCPハンドシェイク、TLSネゴシエーションに必要なラウンドトリップタイム(RTT)が本質的に短縮されます。CDNでホストされているLCP画像の場合、これは読み込み遅延を直接的に減らします。
- 画像CDN:特化型の画像CDNは二重のメリットをもたらします。標準的なCDNの地理的近接性という利点を提供しながら、オンザフライでの画像サイズ変更、圧縮、AVIFやWebPのようなモダンなフォーマットへの変換など、リソース読み込み時間を短縮する多くの複雑な最適化を自動化します。
- 高度なプロトコル:多くのモダンなCDNは、TCPの代わりにQUICを使用するHTTP/3を採用しています。HTTP/3は接続セットアップ時間を短縮し、Head-of-Lineブロッキングを緩和するため、全体としてより高速で効率的なリソース配信につながります。
Speculation Rulesによる遅延の完全な排除
Speculation Rules APIを使用すると、後続のナビゲーションでLCPの遅延を完全に排除できます。
メカニズム
このAPIを使用すると、ユーザーが次に遷移する可能性が高いURLを宣言的にブラウザに伝えることができます。ブラウザはこれらのルールに基づき、ユーザーがリンクをクリックする前に、ターゲットページをバックグラウンドの非表示タブで事前レンダリング(prerender)することを選択できます。
LCPへの影響
ユーザーが事前レンダリングされたページへのリンクをクリックすると、画面遷移はほぼ瞬時に行われます。ページはバックグラウンドで既に完全に読み込まれ、レンダリングされているためです。このナビゲーションにおいて、TTFB、リソース読み込み遅延、リソース読み込み時間、要素のレンダリング遅延は、ユーザーの視点から事実上ほぼゼロに短縮されます。
ユースケースの例
Eコマースのカテゴリページで、Speculation Rulesを利用してリスト上位のいくつかの商品詳細ページを事前レンダリングできます。ユーザーがそれらの商品をクリックすると、ページは瞬時に表示されます。
ケーススタディの統合:理論から実践へ
これらの最適化は、現実世界で測定可能な影響を与えます。
- ケース1:プリロードの劇的な効果:DebugBearがリソース読み込み遅延の大きいページで実施した実験が、劇的な例を提供しています。LCP画像がリクエストチェーンに隠れていたため、リソース読み込み遅延がLCP全体の驚異的な75%を占めていました。単一の
<link rel="preload">ヒントを実装して画像を早期に検出可能にすることで、リソース読み込み遅延はLCPのわずか2%に減少しました。これは、単純なアーキテクチャの修正がどれほど巨大なパフォーマンスのボトルネックを解決できるかを示しています。 - ケース2:現実世界の
loading="lazy"アンチパターン:Stack Overflowのある開発者は、高速なネットワークにもかかわらず、デスクトップのLCPで不可解な1,430msの読み込み遅延が起きていると報告しました。原因を追跡したところ、画像最適化プラグインが、src属性を透明なプレースホルダーSVGに置き換えることでLCP画像に誤ってlazy loadingを適用していました。決定的な解決策は、LCP要素に対するこの動作を無効にし、イーガー(eager)に検出および読み込みできるようにすることでした。これは、サードパーティツールが意図せず深刻な読み込み遅延を引き起こす仕組みを示しています。 - ケース3:
fetchpriorityによるパフォーマンス向上:Googleフライトのケーススタディは、明示的な優先順位付けの影響を明確に証明しています。ページのLCP背景画像にfetchpriority="high"を追加するだけで、LCPスコアは2.6秒から1.9秒へと700ms改善されました。これは、リソースが検出可能であっても、ネットワーク帯域幅の競争に勝つためにはその重要性の高さをブラウザに伝えることが不可欠であることを示しています。
Chrome DevToolsでのネットワーク検査:Ctrl + Shift + IのショートカットでChromeのDeveloper Toolsを開き、「Network」タブを選択してページを再読み込みします。読み込みの順序を確認してください。LCPリソースは、最初にダウンロードキューに入れられる項目の1つであるべきです。他の要素より遅れている場合、リソース読み込み遅延の問題があります。以下は、リソース読み込み遅延が最適化されていないサイトの例です。

RUM (Real User Monitoring) データを使用する:RUMツールは多くの場合、LCPの属性データを記録します。RUMを使用すると、LCPのサブパートの内訳を(時系列またはページ単位で)視覚化でき、サイト全体またはページごとのLCP要素の読み込み遅延を明確に把握できます。以下の例は、グローバルなLCPの内訳とそれに対応する読み込み遅延を示しています。

リソース読み込み遅延を改善する方法
リソース読み込み遅延は、リソースのダウンロード順序とタイミングが最適でない場合に発生します。これを修正する直接的な方法は、本質的に2つあります。LCPリソースの優先度を上げるか、LCP以外のリソースの優先度を下げるかです。いくつかの一般的なパターンを見ていきましょう。
LCPのヒント - プリロードスキャナーを理解する:モダンブラウザはプリロードスキャナーと呼ばれる仕組みを使用し、HTMLを素早くスキャンしてリソースをダウンロードキューに入れます。リソースがプリロードスキャナーによってキューに入れられない場合、より遅いDOMパーサーを待つことになり、遅延が発生します。LCPリソースがプリロードスキャナーによって検出されるようにすることは、読み込み遅延を減らす上で非常に大きな違いを生みます。
1. HTML構造を最適化する
ブラウザ(またはプリロードスキャナー)はHTMLを上から下へと処理し、リソースが現れる順にキューに入れます。つまり、LCPリソースがHTMLの上部にあるほど、より早くキューに入れられます。これを最適化するには、HTMLの上部から不要なリソースを削除するか、遅延させてください。
- 重要でない、または隠れた画像のlazy loading:サイトの言語別バージョンの国旗やメニュー内の画像などが、サイトのHTMLの最上部にあることがあります。これらの画像は、LCP要素に比べて重要度がはるかに低いです。これらの画像にlazy loadingを適用することで、プリロードスキャナーはこれらをスキップし、読み込みプロセスの少し後でキューに入れるようになります。
- 重要でないスクリプトをページの下部に移動する:初期読み込みに全く不要なスクリプトはページの下部に移動し、重要なリソースを遅延させないようにします。チャットウィジェットがその例です。ページが表示される前にチャットを必要としたユーザーは、インターネットの歴史上存在しません。
2. 背景画像を避ける
背景画像はプリロードスキャナーから見えないため、常にずっと遅いDOMパーサーによってキューに入れられます。この遅延を避けるには、代わりに通常の<img>タグを使用し、CSSプロパティのobject-fit: coverと組み合わせて背景画像の外観を模倣してください。この方法なら、プリロードスキャナーが画像を検出し、直ちにキューに入れることができます。
3. fetchpriorityを使用する
LCP要素にfetchpriority="high"属性を追加し、ブラウザに対して最初からこのリソースを優先するようヒントを与えます。通常、画像はデフォルトで低または中程度の優先度で読み込まれます。レイアウトフェーズ中に、ブラウザは可視要素を高優先度にアップグレードします。fetchpriority="high"を設定することで、ダウンロードが最初から高い優先度で開始され、LCPの高速化が保証されます。
fetchpriorityは、要素の相対的な優先度を設定する(この場合、その画像が他の画像よりも相対的に重要であることを示す)だけであるため、一般にプリロードよりも影響が少なく(そして効果も少なく)なります。スタイルシートやノンブロッキングスクリプトなどよりも優先されるわけではありません。
<img src="hero-image.jpg" alt="Hero Image" fetchpriority="high">4. プリロードを実装する
プリロードは、プリロードスキャナーがファイルをキューに入れる順序を変更します。ページのhead内に<link rel="preload">タグを配置し、LCP画像などの重要なリソースをできるだけ早く取得するようブラウザに指示します。プリロードは、HTMLの後半で参照される(したがって後でキューに入れられる)リソースを事前読み込みするためや、HTML内でまだ参照されていないリソース(一部のスライダーなど)を事前読み込みするために使用できます。最大の効果を得るには、ページのhead内でスタイルシートの後、スクリプトの前にプリロードを配置することを推奨します。
<link rel="preload" as="image" href="hero-image.jpg">5. スタイルを最適化する
スタイルシートは通常、LCPリソースよりも前にキューに入れられますが、それには正当な理由があります。スタイルシートがなければ、ブラウザはページがどのように表示されるか分からず、レンダリングフェーズを開始できません。しかし、大きすぎるCSSサイズや多すぎるスタイルシートは、初期の帯域幅をLCPリソースと奪い合うことになります。
6. 効率的なlazy loadingを実装する
loading属性は諸刃の剣になり得ます。LCPリソースにはloading="eager"を使用し(ブラウザのデフォルトが"eager"であるため単に属性を省略しても構いません)、画面外の画像にはloading="lazy"を適用してください。
- LCP要素をEager Loadする:LCP要素にlazy loadingを適用すると、プリロードスキャナーによってキューに入れられず、読み込みが大幅に遅れてパフォーマンスに悪影響を与えます。
- viewport内の画像をlazy loadingする:可視viewport内にあるもののLCPリソースではない画像については、
loading="lazy"を使用してダウンロードキューへの追加を少し遅らせます。これにより、LCPリソースとの帯域幅の競合が緩和されます。 - 画面外の画像でのlazy loadingを避ける:可視viewportにない画像は一切ダウンロードをトリガーしないため、帯域幅の競合が完全に排除されます。
7. ブラウザキャッシュ
ブラウザキャッシュを利用すると、ユーザーのデバイスに既にローカル保存されているリソースへのネットワークリクエストをスキップできます。最初のページビューを高速化することはありませんが、後続のページビューや再訪問者の読み込み時間を改善します。ブラウザキャッシュがリソース読み込み遅延の改善にどう役立つかは以下の通りです。
- 競合するリソースをキャッシュする:LCPリソース自体をキャッシュするのも優れた戦略ですが、スクリプト、スタイルシート、画像など、LCPリソースと競合したり遅延させたりする可能性のあるネットワークリソースを保存することで、ブラウザキャッシュはLCPのリソース読み込み遅延を改善します。
- サーバー負荷の軽減:キャッシュによりサーバーに送信されるリクエストの数が減少し、帯域幅が解放され、サーバーのCPUサイクルが削減されることで、他のリソースのパフォーマンスが向上する可能性があります。
8. Speculation Rulesを使用する
Speculation Rulesにより、ブラウザはユーザーのナビゲーション予測に基づいてウェブページをプリフェッチまたは事前レンダリングできます。プリフェッチはLCPのTime to First Byteサブパートを実質的に排除し、リソース読み込み遅延には影響を与えません。事前レンダリングは次のページを非表示タブでレンダリングし、すべてのページリソースをダウンロードします。この事前レンダリングされたページのLCP内訳の例が示すように、これによりLCP要素のすべての読み込み遅延が排除されます。

9. クライアントサイドレンダリングを避ける
次のステップ:LCPの最適化を続ける
リソース読み込み遅延は、4つあるLCPフェーズの1つです。検出の遅延を最小限に抑えたら、以下のガイドに進んでください。
- LCP問題の特定と修正:すべてのLCP問題を発見して修正するための完全な診断手法。
- LCP画像の最適化:画像フォーマットの選択、レスポンシブ画像、プリロード、および画像に関するよくある間違い。
- リソース読み込み時間:ブラウザがリソースを検出した後、圧縮、モダンなフォーマット、CDNの最適化を通じてダウンロードにかかる時間を短縮する。
- 要素のレンダリング遅延:リソースのダウンロード後、main threadをクリアすることで、ブラウザが即座に描画できるようにする。