リソースの優先順位付けに関するCore Web Vitalsガイド

最初に読み込むリソースと待機させるリソースを制御する

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-02-25

リソースの優先順位付けに関するCore Web Vitalsガイド

ブラウザのデフォルトの優先順位付けエンジンは、ヒューリスティクス(ファイルの種類とドキュメント内の位置に基づく不完全な推測)に基づいて動作します。リソースは、preloadスキャナまたはDOMパーサーのいずれかによって検出されたタイミングに基づいてキューに入れられます。

2026年2月にArjen Karelによって最終レビューされました

ネットワーク帯域幅とCPUが無限のリソースではないことを考慮すると、これは問題になる可能性があります。例えば、低優先度のトラッキングスクリプトをダウンロードするために転送されるすべてのバイトは、Largest Contentful Paint (LCP)に必要なバイトと直接競合します。

ただし、これはブラウザの責任ではありません。この例のHTMLでは、ブラウザは誤ったアセットを優先し、重要なレンダリングを遅らせてしまったことを知る由もありませんでした。

何が重要であるかを把握しているのはあなた自身です。そして、あなたは2つのメカニズムを通じてこのスケジュールを制御できます。それは、優先順位付け(重要なシグナルを高めること)と優先順位の引き下げ(重要でないリソースのスケジュールを、それらが邪魔にならないタイミングまで遅らせること)です。

ブラウザのヒューリスティクスの制限

ブラウザは、「計算された優先度」スコアに基づいて優先順位を割り当てます。このスコアは、アセットのタイプ(CSS、Script、Image)とHTML/DOM内での位置から算出されます。シンプルなドキュメントに対しては概ね有効ですが、リソースが早期に(preloadスキャナによって)認識されない場合や、間違ったリソースが早期ダウンロードのトリガーとなってしまう場合には、このシステムは機能しません。

Chromeのデフォルトの優先順位レベル

Chromeでは、内部的に5つの優先順位レベル(Highest、High、Medium、Low、Lowest)を使用しています。デフォルトでは次のように割り当てられます。

リソース デフォルトの優先度 fetchpriority="high"を使用した場合 fetchpriority="low"を使用した場合
CSS (<head>内) Highest (すでに最大) High
Script (ブロッキング、<head>内) Highest (すでに最大) Low
Script (async / defer) Low High Lowest
Font (preload経由) Highest (すでに最大) n/a
Font (CSS内) High n/a n/a
Image (デフォルト) Low High Lowest
Image (最初の5つの大きな画像) Medium High Low
Image (レイアウト後、ビューポート内) High (すでにHigh) n/a

fetchpriority属性は、<img><link><script>要素でサポートされています。この属性はグローバルブラウザサポートの93%(Chrome 102+、Firefox 132+、Safari 17.2+、Edge 102+)を持ち、プログレッシブエンハンスメントとして機能します。つまり、サポートしていないブラウザは単にこれを無視します。2025年のWeb Almanacによると、モバイルページの17%が現在fetchpriority="high"を使用していますが、fetchpriority="low"を使用しているのはわずか0.3%です。これは、優先順位の引き下げが非常に活用されていない最適化手法であることを意味しています。

Preloadスキャナの制限

リソースの検出を高速化するために、ブラウザは「preloadスキャナ」という機能を採用しています。これは、メインのHTMLパーサーよりも先行してリソースURLを検出する軽量なパーサーです。このスキャナには、(高速かつ効果的であるための)制限があります。HTMLのみを解析し、CSSファイル内を読み取ることができず、JavaScriptを実行せず、レンダリングも行いません(そのため、リソースがビューポート内で表示されるかどうかを判断できません)。

その結果、スタイルシート内で参照されているリソース(背景画像やWebフォントなど)、スクリプトによって挿入されたリソース、あるいは遅延読み込み(lazy load)されたリソースは、メインパーサーがウェブページ全体をダウンロードして処理するまでスキップされます。これにより「検出の遅延」が発生し、ブラウザは実質的に重要なアセットの存在を認識できなくなります。

リソースの競合

ブラウザがアセットを検出すると、多くの場合、他の保留中のリクエストと同時にダウンロードしようとします。重要なLCPイメージが、中程度の優先度のスクリプトや重要でない画像(フッターのソーシャルメディアアイコンなど)と競合すると、利用可能な帯域幅が分割されてしまいます。この競合により両方の読み込み時間が長くなり、LCPの指標が「要改善(Needs Improvement)」の領域に押し下げられてしまいます。

手動による優先順位付け戦略

高速なレンダリングパスを構築するには、手動で介入する必要があります。目標は、LCPのための帯域幅を最大化し、それ以外のすべてのものの帯域幅を最小化することです。CoreDashで監視されているサイト全体で見ると、LCPイメージにfetchpriority="high"を使用しているサイトの82%がLCPの基準をクリアしているのに対し、使用していないサイトでは61%に留まっています。

1. Preloadによる検出の修正

隠れたアセットをpreloadスキャナに手動で公開する必要があります。重要なリソースをrel="preload"を使用してHTMLの<head>に移動することで、ブラウザにそれらを直ちに認識させ、検出の遅延を解消します。完全な手順については、LCPイメージのpreloadに関するガイドを参照してください。

実装方法:

<!-- フォントを直ちにスキャナに公開する -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-bold.woff2" crossorigin>

<!-- LCPの背景画像を直ちに公開する -->
<link rel="preload" as="image" href="/images/hero-banner.jpg" fetchpriority="high">

さらに早い段階での検出には、HTMLレスポンスが到着する前にブラウザにpreloadシグナルを送信する103 Early Hintsの利用を検討してください。

2. LCPヒューリスティクスのオーバーライド

ブラウザは最初のフェッチ中には最終的なレイアウトの寸法がわからないため、画像に対して「Low」や「Medium」の優先順位を割り当てることがよくあります。ブラウザはレンダリングツリーが構築されるまで、その画像がLCPであるかどうかを判断できませんが、それでは手遅れです。

実装方法:

fetchpriority="high"を使用して、LCP要素に「High」の優先順位ステータスを強制します。これにより内部のヒューリスティクスがバイパスされ、画像がダウンロードキューの先頭に配置されます。Googleフライトでは、この単一の属性を追加することで、LCPが2.6秒から1.9秒(0.7秒の改善)に短縮されました。

<!-- 直ちに高優先度のフェッチを強制する -->
<img src="hero.jpg" alt="Hero Product" fetchpriority="high">

ここでの最悪のミスは、LCPイメージを遅延読み込み(lazy load)することです。これにより、ページ上で最も重要な要素の優先順位が積極的に引き下げられてしまいます。

3. 重要でない画像の優先順位引き下げ

優先順位を上げることよりも、帯域幅を解放することのほうが効果的な場合がよくあります。重要なリソースのためにネットワークパイプを空けるには、必須ではないアセットの読み込みを明示的に遅らせる必要があります。

実装方法:

  • スクロールしなければ見えない位置(Below the fold): ユーザーがスクロールするまでオフスクリーン画像を遅延させるには、loading="lazy"を使用します。
  • ファーストビュー(Above the fold)、サブの要素: カルーセルのスライドなど、最初にレンダリングされるもののLCPより重要度が低いサブの視覚要素には、fetchpriority="low"を使用します。
  • ファーストビュー、視覚的に重要でない要素: loading="lazy"を使用してpreloadスキャナをバイパスし、低い帯域幅の優先度を割り当てます。これは、最初のレンダリング時に目を引くことはないものの、早期に多くの帯域幅リクエストをトリガーする可能性のある、国旗やアイコンなどの小さな画像に便利です。
<!-- LCPイメージ:最高優先度 -->
<img src="slide-1.jpg" fetchpriority="high">

<!-- サブのカルーセル画像:直ちにフェッチするが、帯域幅の使用は低く設定 -->
<img src="slide-2.jpg" fetchpriority="low">

<!-- 翻訳の国旗:ビューポート内にある間、preloadスキャナから隠す -->
<img src="dutch-flag.jpg" loading="lazy" fetchpriority="low">

<!-- オフスクリーン画像:遅延フェッチ -->
<img src="footer-promo.jpg" loading="lazy">

4. スクリプト実行の制御

JavaScriptはDOMパーサーをブロックします。標準の<script>タグを使用すると、ブラウザはHTMLの解析を停止してファイルをダウンロードし、実行します。制御されていないスクリプトの実行は、メインスレッドをブロックすることでInteraction to Next Paint (INP)に直接悪影響を与えます。

実装方法:

  • defer: アプリケーションのロジックに使用します。並行してダウンロードされ(優先度はLow)、HTMLの解析が完全に完了した後にのみ実行されるため、依存関係の順序が保持されます。
  • async: 独立したサードパーティスクリプト(アナリティクスなど)に使用します。並行してダウンロードされ、完了次第すぐに実行されます。順序は無視されます。
  • async + fetchpriority="high": 解析をブロックすることなく高速なダウンロードが必要な、重要なasyncスクリプト(A/Bテストなど)に使用します。これにより、実行を非ブロック状態に保ちながら、ダウンロードの優先度をLowからHighに引き上げます。
  • Inject(動的挿入): preloadスキャナをバイパスするため、早期の帯域幅と競合しません。挿入されたスクリプトはasyncとして扱われます。
  • Schedule + Inject(スケジュールと動的挿入): loadイベントの発生時など、後からスクリプトを挿入します。
<!-- アプリケーションロジック:非ブロック、実行順序を保持 -->
<script src="app.js" defer></script>

<!-- サードパーティの同意:非ブロック、独立した実行 -->
<script src="consent.js" async></script>

<!-- 重要なasync:高速なダウンロード、非ブロック実行 -->
<script src="ab-test.js" async fetchpriority="high"></script>

<script>
  /* 挿入されるアナリティクスの例 */
  const script = document.createElement('script');
  script.src = 'analytics.js';
  script.async = true;
  document.head.appendChild(script);

  /* チャットのスケジュールと挿入の例 */
  window.addEventListener('load', () => {
    const chatScript = document.createElement('script');
    chatScript.src = 'chat-widget.js';
    document.head.appendChild(chatScript);
  });
</script>

利用可能なすべての手法の包括的な内訳については、JavaScriptを遅延させる16の方法およびasyncとdefer JavaScriptの比較を参照してください。重要度に基づくスクリプトの分類に関するガイダンスについては、JavaScriptの優先順位レベルを参照してください。

5. CSSレンダリングのブロック解除

CSSは設計上、レンダリングをブロックするリソースです。ブラウザはCSSがないとページがどのように見えるかわからないため、最初にスタイルシートをダウンロードして解析します。

最適化戦略:

  • @importを避ける: これはパフォーマンスに壊滅的な影響を与える順次的な依存関係のチェーンを作り出します。
  • バンドルサイズの最適化: 3kB未満のCSSファイル(オーバーヘッド)や20kBを超えるCSSファイル(ブロック)を避けます。理想的には、約15kBのファイルをターゲットにします。
  • 非同期読み込み: オフスクリーンのスタイルを非同期で読み込み、クリティカルパスのブロックを解除します。
  • Critical CSSのトレードオフ: Critical CSSをインライン化すると最初のページビューは改善されますが、ブラウザのキャッシュがバイパスされるため、それ以降のページビューが遅延する可能性があります。

実装方法:

@importを完全に排除します。並行読み込みには<link>タグを使用します。非クリティカルなCSS(印刷用スタイルなど)の場合は、メディア属性を使用してメインスレッドのブロックを解除します。CSSの最適化の詳細については、未使用のCSSの削除を参照してください。

<!-- クリティカルなCSS:レンダリングをブロックする(正しい) -->
<link rel="stylesheet" href="main.css">

<!-- 印刷用CSS:印刷イベントが発生するまで非ブロック -->
<link rel="stylesheet" href="print.css" media="print">

<!-- 非同期パターン:低い優先度で読み込まれ、ロード時に適用される -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">

6. フォントレンダリングの安定化

フォントは重いブロッキングリソースです。効果的な優先順位付けを行うには、ダウンロードするものを厳密に制限し、そのレンダリング方法を制御する必要があります。

最適化戦略:

  • 厳格なpreloadの制限: 最も重要な1〜2個のフォントファイル(通常はLCPのテキスト)のみをpreloadします。5つ以上のフォントをpreloadすると、帯域幅が詰まります。
  • セルフホスト: サードパーティのCDNから読み込むのではなく、Webフォントをセルフホストします。これにより、余分な接続のセットアップが不要になります。
  • ペイロードの削減: 可変フォント(すべてのウェイトを1つのファイルで提供)とサブセット化(未使用の文字の削除)を使用して、ファイルサイズを最小限に抑えます。
  • レンダリング戦略:

実装方法:

<!-- クリティカルなサブセット(ヘッダー + 本文など)のみをpreloadする -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>

<style>
  @font-face {
    font-family: 'Inter Variable';
    src: url('/fonts/inter-var.woff2') format('woff2-variations');
    /* 安定性の要件に基づいて選択: */
    font-display: optional; /* レイアウトシフトは発生しないが、フォントがフォールバックのままになる可能性がある */
    /* font-display: swap;     テキストが最も早く表示されるが、レイアウトシフトのリスクがある */
  }
</style>

7. 接続の高速化

ブラウザがサードパーティのオリジンからリソースをダウンロードする前に、DNSルックアップを実行し、TCP接続を確立し、TLS暗号化をネゴシエートする必要があります。これには時間がかかります。ブラウザに接続のセットアップを早期に行うよう指示することで、この遅延を排除できます。

実装方法:

  • preconnect: ブラウザが必要とすることがわかっている、クリティカルなサードパーティのオリジンに使用します。これにより、完全なハンドシェイク(DNS + TCP + TLS)が事前に行われます。
  • dns-prefetch: クリティカルではないオリジンに使用します。DNSの解決のみを実行しますが、これだけでも20〜120ミリ秒の節約になり、動作も軽量です。
<!-- クリティカルなサードパーティ:完全な早期接続 -->
<link rel="preconnect" href="https://cdn.example.com">

<!-- 古いブラウザ向けのフォールバック -->
<link rel="dns-prefetch" href="https://cdn.example.com">

preconnectは2〜4つのオリジンに制限してください。各接続はCPUと帯域幅を消費します。preconnectが多すぎると、実際のリソースのダウンロードと競合し、パフォーマンスを向上させるどころか悪化させる可能性があります。2025年のWeb Almanacによると、ページの22%がpreconnectを使用し、24%がdns-prefetchを使用しています。ブロッキングリソースよりも前の、<head>内の可能な限り早い位置に両方を配置してください。

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Lighthouseのスコアは全体像ではありません。

実ユーザーはAndroid端末で4Gを使っています。その人たちが実際に何を体験しているかを分析します。

フィールドデータを分析
リソースの優先順位付けに関するCore Web VitalsガイドCore Web Vitals リソースの優先順位付けに関するCore Web Vitalsガイド