Fetch Priority API は、ブラウザに対するリソースの相対的な優先度を示します。これにより、読み込みを最適化し、Core Web Vitals を改善できます。
対応ブラウザ
-
<ph type="x-smartling-placeholder">
-
<ph type="x-smartling-placeholder">
-
<ph type="x-smartling-placeholder">
-
<ph type="x-smartling-placeholder">
ブラウザはウェブページを解析し、画像、スクリプト、CSS などのリソースの検出とダウンロードを開始すると、取得用の priority
を割り当てて、最適な順序でダウンロードできるようにします。通常、リソースの優先度は、その内容とドキュメント内の場所によって異なります。たとえば、ビューポート内の画像の優先度を High
にして、<head>
で <link>
を使用する、早期に読み込まれるレンダリング ブロック CSS の優先度を Very High
にできます。ブラウザは、優先順位の割り当ては適切に行うことができていますが、すべてのケースで最適であるとは限りません。
このページでは、Fetch Priority API と fetchpriority
HTML 属性について説明します。この属性を使用すると、リソースの相対的な優先度(high
または low
)を指定できます。取得優先度は、Core Web Vitals の最適化に役立ちます。
概要
優先取得が役立つ主な領域:
- 画像要素に
fetchpriority="high"
を指定して LCP 画像の優先度を上げ、LCP が早く発生するようにします。 - 現在最も一般的なハッキング(
async
スクリプトの<link rel="preload">
を挿入)よりも優れたセマンティクスを使用して、async
スクリプトの優先度を上げました。 - 画像でのシーケンスを改善するために、後期身体スクリプトの優先度を下げます。
![Google フライトのホームページの 2 つのテストを比較したフィルムストリップ ビュー。一番下の Fetch Priority を使用して、ヒーロー画像の優先度を高め、LCP を 0.7 秒低減させています。](https://web.dev/static/articles/fetch-priority/image/a-filmstrip-view-comparin-298b8fe7eedbb.png?authuser=7&hl=ja)
これまで、デベロッパーがプリロードと事前接続を使用してリソースの優先度に影響を与えることは限定的でした。プリロードでは、読み込む必要のある重要なリソースをブラウザが自然と検出する前に、その情報をブラウザに伝えることができます。これは、スタイルシートに含まれるフォント、背景画像、スクリプトから読み込まれるリソースなど、見つけにくいリソースの場合に特に便利です。事前接続は、クロスオリジン サーバーへの接続をウォームアップし、最初のバイトまでの時間などの指標を改善するのに役立ちます。オリジンはわかっていても、必要になるリソースの正確な URL が必ずしもわからない場合に便利です。
取得優先度は、こちらのリソースヒントを補完するものです。これは、fetchpriority
属性を通じて利用できるマークアップ ベースのシグナルで、デベロッパーはこれを使用して特定のリソースの相対的な優先度を指定できます。また、JavaScript や Fetch API で priority
プロパティを使用してこれらのヒントを使用して、データに対して行われるリソースの取得の優先度に影響を与えることもできます。フェッチ優先度はプリロードを補完することもできます。Largest Contentful Paint 画像を取得します。プリロードされた画像の優先度は低くなります。優先度の低い他のリソースからプッシュバックされた場合は、優先取得を使用することで、イメージの読み込み時間を改善できます。
リソースの優先度
リソースのダウンロード順序は、ブラウザに割り当てられた ページ上のすべてのリソースです。優先度の計算に影響する要素 次のロジックが含まれます。
- CSS、フォント、スクリプト、画像、サードパーティ リソースなどのリソースの種類。
- ドキュメントがリソースを参照する場所または順序。
- スクリプトで
async
属性またはdefer
属性を使用するかどうか。
次の表は、Chrome で大部分のリソースの優先順位と順序付けがどのように行われるかを示しています。
<ph type="x-smartling-placeholder">レイアウト ブロッキング フェーズで読み込む | レイアウト ブロッキング フェーズで一度に 1 つずつ読み込む | ||||
---|---|---|---|---|---|
Blink 優先機能 |
VeryHigh | 高 | 中 | 低 | VeryLow |
DevTools Priority |
最高 | 高 | 中 | 低 | 最低 |
メインリソース | |||||
CSS(早期**) | CSS(遅延**) | CSS(メディアの不一致***) | |||
スクリプト(早期** またはプリロード スキャナからのもの以外) | スクリプト(後期**) | スクリプト(非同期) | |||
フォント | フォント(rel=preload) | ||||
インポート | |||||
画像(ビューポート内) | 画像(最初の 5 枚の画像 > 10,000px2) | 画像 | |||
メディア(動画/音声) | |||||
プリフェッチ | |||||
XSL | |||||
XHR(同期) | XHR/取得*(非同期) |
ブラウザは、同じ優先度で、検出された順にリソースをダウンロードします。Chrome デベロッパー ツールの [ネットワーク] タブで、ページの読み込み時にさまざまなリソースに割り当てられた優先度を確認できます。(表の見出しを右クリックして、チェックを入れて、Priority 列を必ず含めてください)。
<ph type="x-smartling-placeholder">![フォント リソースの一覧が表示されている Chrome の DevTools の [ネットワーク] タブ。これらはすべて最優先事項です。](https://web.dev/static/articles/fetch-priority/image/a-screenshot-assets-list-fdcb380583bdd.png?authuser=7&hl=ja)
type = "font"
の優先度![フォント リソースの一覧が表示されている Chrome の DevTools の [ネットワーク] タブ。優先度が「低」と「高」が混在しています。](https://web.dev/static/articles/fetch-priority/image/a-screenshot-assets-list-f556ffc3eb8e4.png?authuser=7&hl=ja)
type = "script"
の優先度。優先度が変更された場合は、[Big request rows] 設定またはツールチップに初期優先度と最終優先度の両方が表示されます。
<ph type="x-smartling-placeholder">![Chrome の DevTools の [Network] タブ。「Big request rows」設定がオンになっていて、[優先度] 列には優先度が「高」で、その下に「中」の別の初期優先度の画像が表示されます。ツールチップにも同じ内容が表示されます。](https://web.dev/static/articles/fetch-priority/image/initial-final-priority.png?authuser=7&hl=ja)
取得優先度が必要になるのは、どのような場合ですか。
ブラウザの優先順位付けのロジックについて理解したところで、ページのダウンロード順序を微調整して、パフォーマンスと Core Web Vitals を最適化できます。リソースのダウンロードの優先度に影響を与えるために変更できる変更の例を以下に示します。
<script>
や<link>
などのリソースタグは、ブラウザにダウンロードされる順序に配置します。同じ優先度のリソースは、通常、検出された順に読み込まれます。preload
リソースヒントを使用して、必要なリソースを早い段階でダウンロードします。特に、ブラウザで早期に発見するのが難しいリソースの場合に特に役立ちます。async
またはdefer
を使用すると、他のリソースをブロックせずにスクリプトをダウンロードします。- スクロールしなければ見えない範囲のコンテンツを遅延読み込みして、ブラウザがスクロールせずに見える範囲のより重要なリソースに使用可能な帯域幅を使用できるようにします。
これらの手法は、ブラウザの優先順位計算を制御するのに役立ち、パフォーマンスと Core Web Vitals を向上させます。たとえば、重要な背景画像をプリロードすると、それをより早期に発見できるため、Largest Contentful Paint(LCP)が改善されます。
場合によっては、これらのハンドルだけでは、アプリケーションに最適なリソースの優先順位を決めるのに十分でないことがあります。フェッチ優先度が役立つシナリオをいくつか紹介します。
- スクロールせずに見える範囲に画像が複数ありますが、すべての画像の優先度を同じにする必要はありません。たとえば、画像カルーセルでは、最初に表示される画像のみの優先度を高くする必要があります。通常は画面外の他の画像については、優先度を低く設定できます。
- 通常、ビューポート内の画像は
Low
の優先度で開始します。レイアウトの完了後、Chrome はそれがビューポートに表示されていることを検出し、優先度を上げます。そのため、ヒーロー画像などの重要な画像の読み込みに大幅な遅延が発生します。マークアップで取得優先度を指定すると、画像の優先度をHigh
から開始して、はるかに早く画像の読み込みを開始できます。これをある程度自動化するために、Chrome で最初の 5 つの大きい画像の優先度がMedium
に設定されますが、明示的なfetchpriority="high"
の方がさらに効果的です。
CSS の背景として含まれる LCP 画像を早期に検出するには、引き続きプリロードが必要です。背景画像をブーストします優先度を設定する場合は、プリロードにfetchpriority='high'
を含めます。 - スクリプトを
async
またはdefer
として宣言すると、ブラウザはスクリプトを非同期で読み込むよう指示します。ただし、優先度の表に示されているように、これらのスクリプトには「低」のあります。特にユーザー エクスペリエンスに重要なスクリプトでは、非同期ダウンロードを確保しつつ、優先度を上げることをおすすめします。 - JavaScript
fetch()
API を使用してリソースやデータを非同期で取得すると、ブラウザによって優先度High
が割り当てられます。特にバックグラウンド API 呼び出しとユーザー入力に応答する API 呼び出しが混在している場合には、一部のフェッチを低い優先度で実行することもあります。バックグラウンド API 呼び出しを優先度Low
としてマークし、インタラクティブ API 呼び出しを優先度High
としてマークします。 - ブラウザは CSS とフォントに
High
優先度を割り当てますが、一部のリソースが他のリソースよりも重要となる場合があります。フェッチ優先度を使用すると、重要でないリソースの優先度を下げることができます(初期の CSS はレンダリング ブロックであるため、通常はHigh
優先度になります)。
fetchpriority
属性
fetchpriority
HTML 属性を使用して、link
、img
、または script
タグでダウンロードする際に、CSS、フォント、スクリプト、画像などのリソースタイプのダウンロード優先度を指定します。以下の値を取ります。
high
: リソースの優先度が高く、ブラウザ独自のヒューリスティックにより優先度が上がらない限り、ブラウザが通常よりも優先度を高くする必要があります。low
: リソースの優先度が低いため、ブラウザでヒューリスティックで許容できる場合は優先度を下げます。auto
: デフォルト値。ブラウザが適切な優先度を選択できるようにします。
マークアップで fetchpriority
属性を使用する例と、スクリプトと同等の priority
プロパティを次に示します。
<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">
<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">
<script>
fetch('https://example.com/', {priority: 'low'})
.then(data => {
// Trigger a low priority fetch
});
</script>
ブラウザの優先順位と fetchpriority
の影響
次の表に示すように、さまざまなリソースに fetchpriority
属性を適用して、計算される優先度を増減できます。各行の fetchpriority="auto"
(◉)は、そのタイプのリソースのデフォルトの優先度を示します。(Google ドキュメントでも確認できます)。
レイアウト ブロッキング フェーズで読み込む | レイアウト ブロッキング フェーズで 1 つずつ読み込む | ||||
---|---|---|---|---|---|
Blink 優先機能 |
VeryHigh | 高 | 中 | 低 | VeryLow |
DevTools Priority |
最高 | 高 | 中 | 低 | 最低 |
主なリソース | ◉ | ||||
CSS(早期**) | ⬆◉ | ⬇ | |||
CSS(遅延**) | ⬆ | ◉ | ⬇ | ||
CSS(メディアの不一致***) | ⬆*** | ◉⬇ | |||
スクリプト(早期** またはプリロード スキャナからのもの以外) | ⬆◉ | ⬇ | |||
スクリプト(後期**) | ⬆ | ◉ | ⬇ | ||
スクリプト(async/defer) | ⬆ | ◉⬇ | |||
フォント | ◉ | ||||
フォント(rel=preload) | ⬆◉ | ⬇ | |||
インポート | ◉ | ||||
画像(ビューポート内 - レイアウト後) | ⬆◉ | ⬇ | |||
画像(最初の 5 枚の画像 > 10,000px2) | ⬆ | ◉ | ⬇ | ||
画像 | ⬆ | ◉⬇ | |||
メディア(動画/音声) | ◉ | ||||
XHR(同期)- サポート終了 | ◉ | ||||
XHR/取得*(非同期) | ⬆◉ | ⬇ | |||
プリフェッチ | ◉ | ||||
XSL | ◉ |
fetchpriority
は、優先度を明示的に High
または Low
に設定するのではなく、相対的な優先度を設定します。つまり、デフォルトの優先度を適切に増減させます。多くの場合、優先度は High
または Low
になりますが、常にそうとは限りません。たとえば、クリティカルな CSS に fetchpriority="high"
を指定すると、「非常に高い」/「最高」が保持されます。され、これらの要素で fetchpriority="low"
を使用すると、「高」が維持され、あります。どちらの場合も、優先度を High
または Low
に明示的に設定しません。
ユースケース
fetchpriority
属性は、リソースの取得優先度に関するヒントをブラウザに与えたい場合に使用します。
LCP イメージの優先度を上げる
fetchpriority="high"
を指定すると、LCP などの重要なイメージの優先度を上げることができます。
<img src="lcp-image.jpg" fetchpriority="high">
次の比較では、Google フライトのページで、取得優先度を使用したものと使用していない LCP の背景画像を示しています。優先度を「高」に設定すると、LCP が 2.6 秒から 1.9 秒に改善されました。
<ph type="x-smartling-placeholder">スクロールせずに見える範囲の画像の優先度を下げる
fetchpriority="low"
を使用すると、スクロールせずに見える範囲の画像のうち、すぐに重要ではない画像(画像カルーセルのオフスクリーン画像など)の優先度を下げることができます。
<ul class="carousel">
<img src="img/carousel-1.jpg" fetchpriority="high">
<img src="img/carousel-2.jpg" fetchpriority="low">
<img src="img/carousel-3.jpg" fetchpriority="low">
<img src="img/carousel-4.jpg" fetchpriority="low">
</ul>
画像 2 ~ 4 はビューポートの外側に表示されますが、「十分に近い」と見なされる場合がありますhigh
にブーストし、load=lazy
属性が追加された場合でも読み込みます。したがって、fetchpriority="low"
が適切な解決策となります。
Oodle アプリの以前のテストでは、このメソッドを使用して、読み込み時に表示されない画像の優先度を下げました。ページの読み込み時間を 2 秒短縮しました。
<ph type="x-smartling-placeholder">![Oodle アプリの画像カルーセルで使用した場合の取得優先度の比較。左側のブラウザではカルーセル画像のデフォルトの優先度が設定されていますが、右側の画像よりもダウンロードとペイントに 2 秒ほど時間がかかっています。この例では、最初のカルーセル画像のみの優先度が高く設定されています。](https://web.dev/static/articles/fetch-priority/image/a-side-side-comparison-54fe14438a5c2.png?authuser=7&hl=ja)
プリロードされたリソースの優先度を下げる
プリロードされたリソースが他の重要なリソースと競合しないようにするには、優先度を下げます。この手法は、画像、スクリプト、CSS で使用します。
<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">
<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">
スクリプトの優先順位の変更
ページのインタラクティブにする必要のあるスクリプトは迅速に読み込む必要がありますが、他のより重要なレンダリング ブロック リソースをブロックしないようにする必要があります。このようなケースには、優先度の高い async
のマークを付けることができます。
<script src="async_but_important.js" async fetchpriority="high"></script>
特定の DOM 状態に依存しているスクリプトを async
としてマークすることはできません。ただし、後でページを実行した場合は、低い優先度で読み込むことができます。
<script src="blocking_but_unimportant.js" fetchpriority="low"></script>
これにより、このスクリプトに到達するとパーサーはブロックされますが、それ以前のコンテンツを優先させることができます。
代わりに、完成した DOM が必要な場合は、defer
属性(DOMContentLoaded の後に順番に実行されます)を使用するか、ページ下部の async
を使用することもできます。
重要性の低いデータ取得の優先度を下げる
ブラウザは、高い優先度で fetch
を実行します。同時に実行される可能性がある取得が複数ある場合は、重要度の高いデータの取得にはデフォルトの高い優先度を使用し、重要度の低いデータの優先度は引き下げることができます。
// Important validation data (high by default)
let authenticate = await fetch('/user');
// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});
優先度の実装メモを取得する
取得優先度を使用すると、特定のユースケースでパフォーマンスが向上する場合があります。ただし、取得優先度を使用する際は、以下の点に注意してください。
fetchpriority
属性はヒントであり、ディレクティブではありません。ブラウザはデベロッパーの設定を尊重しようとしますが、リソースの優先度の設定を適用して競合を解決することもできます。フェッチ優先度とプリロードを混同しないでください。
- プリロードは必須のフェッチであり、ヒントではありません。
- プリロードを使用すると、ブラウザはリソースを早期に検出できますが、デフォルトの優先度でリソースが取得されます。逆に、取得優先度は見つけやすさには役立ちませんが、取得優先度を増減することはできます。
- 多くの場合、優先度の変更による影響よりも、プリロードの影響を観察、測定するほうが簡単です。
フェッチ優先度は、優先度をより細かく設定することで、プリロードを補完できます。LCP イメージの
<head>
の最初のアイテムの 1 つとしてプリロードをすでに指定している場合、取得優先度high
によって LCP が大幅に改善されない可能性があります。ただし、他のリソースの読み込み後にプリロードが発生した場合は、high
の取得優先度により LCP をより向上させることができます。重要な画像が CSS の背景画像の場合は、fetchpriority = "high"
でプリロードします。優先順位付けによる読み込み時間の改善は、利用可能なネットワーク帯域幅を奪い合うリソースが多い環境では、より重要になります。これは、並列ダウンロードが不可能な HTTP/1.x 接続や、低帯域幅の HTTP/2 または HTTP/3 接続でよく発生します。そのような場合、優先順位付けによってボトルネックの解決に役立ちます。
CDN では一様に HTTP/2 の優先順位付けが実装されておらず、HTTP/3 の場合も同様です。ブラウザが Fetch Priority の優先度を通知しても、指定した順序でリソースの優先順位が再設定されないことがあります。このため、取得優先度のテストが難しくなります。優先度は、ブラウザ内部で、優先度設定をサポートするプロトコル(HTTP/2 と HTTP/3)で適用されます。優先度の取得は、CDN や送信元のサポートから独立して内部ブラウザの優先順位付けを行うためだけに、やはり有用です。ブラウザがリソースをリクエストすると優先度が変わることが多いからです。たとえば、画像などの優先度の低いリソースは、ブラウザが重要な
<head>
アイテムを処理している間、リクエストされないことがよくあります。最初の設計では、フェッチ優先度をベスト プラクティスとして導入できない場合があります。開発サイクルの後半で、ページ上のさまざまなリソースに優先度を割り当てることができます。想定と異なる場合は、さらに最適化するために Fetch Priority を導入できます。
プリロードは、パーサーによって検出されないリソース(フォント、インポート、バックグラウンド LCP 画像)をプリロードする、意図された目的に使用する必要があります。preload
ヒントの配置は、リソースがプリロードされるタイミングに影響します。
取得優先度とは、リソースがフェッチされるときに、そのリソースをどのようにフェッチするかということです。
プリロードを使用する際のヒント
プリロードを使用する場合は、次の点に注意してください。
- HTTP ヘッダーにプリロードを含めると、読み込み順で他のものよりも前に配置されます。
- 通常、優先度が
Medium
以上のものについては、パーサーが到達する順序でプリロードされます。HTML の先頭にプリロードを含める場合は注意が必要です。 - フォントのプリロードは、おそらく頭の最後または本文の最初に使用するのが最適です。
- インポートのプリロード(動的
import()
またはmodulepreload
)は、インポートを必要とするスクリプトタグの後に実行する必要があります。そのため、依存関係の読み込み中に評価できるように、必ずスクリプトの読み込みまたは解析を行ってください。 - 画像プリロードの優先度は、デフォルトで
Low
またはMedium
に設定されています。非同期スクリプトや他の優先度の低いタグ、または最も優先度が低いタグと比較して、順序を決めてください。
履歴
取得優先度は、2018 年に Chrome でオリジン トライアルとして最初にテストされ、2021 年に再度 importance
属性を使用してテストされました。当時は優先度ヒントと呼ばれていました。その後、ウェブ標準プロセスの一環として、HTML では fetchpriority
、JavaScript の Fetch API では priority
にインターフェースが変更されました。混乱を避けるために、この API を Fetch Priority と呼ぶことにしました。
まとめ
デベロッパーはおそらく、プリロード動作の修正を備えたフェッチ優先度に興味を持つでしょう。また、最近は Core Web Vitals と LCP に重点が置かれています。そこで、希望する読み込みシーケンスを実行するために追加のノブを使用できるようになりました。