fetchpriority属性でLCP画像を最適化する|2026年実践ガイド

(更新: 2026年6月22日 ) パフォーマンス LCP fetchpriority Web Vitals 画像最適化 preload
結論
  • LCP改善の最短ルートは、LCP候補リソース1つにfetchpriority="high"を付け、必要なら<link rel="preload" as="image">と併用することだ。
  • 帯域は有限で、CSS・JS・フォント・サムネイルが同時に走るとヒーロー画像の開始が遅れる。
  • クリティカルレンダリングパス最適化でブロッキングを減らし、HTTP/2・HTTP/3で接続効率を上げたうえで、fetchpriorityは「同一接続内の優先順位付け」の最後の1押しになる。

fetchpriority属性とは

fetchpriorityは、HTML Living StandardおよびFetch Priority APIで定義された、ブラウザへのリソース取得優先度ヒントだ。<img><link><script><iframe>などに付与でき、値はhighlowautoの3種類。

2022年頃のChrome実装から始まり、2026年現在は主要ブラウザで広くサポートされている。Core Web VitalsのLCP(Largest Contentful Paint)改善とセットで語られることが多いが、本質は「限られたネットワーク帯域とHTTP/2・HTTP/3のストリーム枠を、どのリソースに先に割り当てるか」を開発者が指示できる点にある。

fetchpriorityは強制命令ではない。ブラウザはセキュリティ、Same-Origin、リソース種別、既存の優先度キューを総合して最終優先度を決める。それでもLCP画像のように「遅延がそのままLCP悪化に直結する」リソースでは、DevToolsのPriority列に明確な差が出る。

優先度キューとLCPの関係

ブラウザは概ね次の順でリソースをスケジュールする。

  1. Document(HTML) — 常に最優先
  2. preload + fetchpriority=high — クリティカル画像・フォント
  3. CSS(レンダーブロッキング) — CSSOM構築に必要
  4. sync script / import map — パーサー依存
  5. img fetchpriority=high — LCP候補
  6. 通常のimg / script defer / font — Medium付近
  7. fetchpriority=low / prefetch — 明示的に後回し

LCPが2.5秒を超える典型原因の一つは、LCP画像のダウンロード開始(Resource Load Start)が遅いことだ。CSSや同期JSが長い、preloadしていない、同一ページに多数の高優先度リソースがある——fetchpriorityはこの「開始順序と帯域配分」を調整する。

属性値 意味と推奨用途
high 他より先に取得してほしい。LCP候補のヒーロー画像・preloadするクリティカルフォントに限定
low 後回しでよい。Below-the-fold装飾、一覧の2枚目以降のサムネ、prefetch的な先読み
auto ブラウザデフォルト(省略時と同じ)。特別な理由がなければこれ
(省略) autoと同等。LCP候補以外は省略でよい

LCP要素の特定 — Performance Insightsの使い方

fetchpriorityを付ける前に、本当にLCPになっている要素をDevToolsで確認する。推測でヒーロー画像にhighを付けても、実際のLCPが<h1>テキストなら効果は限定的だ。

Chrome DevTools Performance Insights

Chrome 118以降、Performance Insightsパネル(DevTools → Performance insights)がLCP分析に特化している。

  1. 対象URLを開き、DevTools → Performance insightsタブ
  2. Measure page load をクリック(または Ctrl+Shift+E で記録)
  3. レポートの LCP セクションを展開
  4. LCP element に表示されるセレクタ・URLをメモ
  5. LCP breakdown で TTFB / Load delay / Load time / Render delay の内訳を確認

Load delayが大きい場合、HTMLパースや他リソースとの競合で画像取得開始が遅れている。fetchpriority=highとpreloadが有効。Load timeが大きい場合、画像バイトサイズやCDN距離が原因——画像圧縮・WebP/AVIFを先に見る。

1

DevTools → Performance insights → Measure page load

2

LCP element のタグ名・src・セレクタを記録

3

LCP breakdown で Load delay と Load time のどちらが支配的か判断

4

Network タブで該当リクエストの Priority と Initiator を確認

5

high / preload を適用し、同条件で再計測して LCP 時刻を比較

Lighthouseとの使い分け

Lighthouseも「Largest Contentful Paint element」を報告するが、Labデータは1回のシミュレーションだ。fetchpriorityのBefore/Afterは、可能なら同一マシン・同一Throttling(4G Slow / Mobile)で3回ずつ計測し中央値を取る。

Field Data(Search ConsoleのCore Web Vitals、CrUX)ではLCP要素の内訳までは見えない。Labで特定したLCP候補をFieldのLCP悪化ページに当てはめ、優先的に修正する。

LCPがテキストの場合

ECサイトやニュースサイトでは<h1>やリード文がLCPになることがある。この場合fetchpriority on imageより、WebフォントのFOIT/FOUT対策font-display: swap、サブセット化、可変フォント、システムフォントスタック)と、CRP最適化のCSSインライン化が効く。画像にhighを付けてもLCPは動かない。

fetchpriority=high — LCP画像への適用

LCP候補が<img>のとき、次の属性セットが2026年のweb.dev推奨に沿った最小構成だ。

  • fetchpriority="high" — 取得優先度ヒント
  • width / height — CLS防止(レイアウト確定が早いとLCP計測も安定)
  • srcset / sizes — 適切な解像度のみ取得
  • decoding="async" — メインスレッドとの競合緩和(デフォルトでも可)
  • loading属性は付けない — LCP画像にloading="lazy"は禁物

基本的なHTML例

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>fetchpriority LCP デモ</title>

  <!-- クリティカルCSSは短くインライン(CRP参照) -->
  <style>
    body { margin: 0; font-family: system-ui, sans-serif; }
    .hero { display: block; width: 100%; max-height: 70vh; object-fit: cover; }
  </style>

  <!-- LCP画像: パース前に高優先度で開始 -->
  <link rel="preload" as="image"
        href="/images/hero-1200.webp"
        imagesrcset="/images/hero-800.webp 800w, /images/hero-1200.webp 1200w"
        imagesizes="100vw"
        fetchpriority="high">

  <!-- 非クリティカルCSS -->
  <link rel="stylesheet" href="/css/main.css" media="print" onload="this.media='all'">
</head>
<body>
  <header>
    <h1>サービス名</h1>
  </header>

  <main>
    <img
      class="hero"
      src="/images/hero-1200.webp"
      srcset="/images/hero-800.webp 800w, /images/hero-1200.webp 1200w"
      sizes="100vw"
      alt="プロダクトのメインビジュアル"
      width="1200"
      height="630"
      fetchpriority="high"
      decoding="async"
    />

    <p>リード文……</p>
  </main>

  <!-- アプリJSはdefer -->
  <script src="/js/app.js" defer></script>
</body>
</html>

<link rel="preload" as="image">imagesrcset / imagesizesは、<img>完全一致させる。不一致だとブラウザが別URLをpreloadし、帯域の無駄になる。

preloadとimgの二重指定は問題ないか

web.devの「Optimize LCP」および「Preload critical assets」では、LCP画像に対しpreload + imgの両方にfetchpriority=highが例示されている。preloadで早期開始、imgタグでレスポンス再利用(同一URLならキャッシュヒット)——役割が異なる。

highの乱用に注意

同一ページにfetchpriority="high"を5つ付けると、ブラウザ内部で相対優先度が flatten し、LCP画像が再び後ろに回る。原則1〜2リソース(LCP画像 + 必要ならクリティカルフォント)に限定する。

fetchpriority=low — 帯域競合の回避

LCPを改善するもう半分は、LCP以外を意図的に遅らせることだ。Above-the-foldに見えるがLCPではない装飾、カルーセルの2枚目以降、記事グリッドのサムネイルはlowの候補になる。

<section class="article-grid">
  <!-- 1枚目だけLCP候補になりうる場合は auto のまま -->
  <article>
    <img src="/thumb/feature.webp" alt="特集" width="400" height="225" loading="lazy">
  </article>

  <!-- 2枚目以降は low + lazy で帯域を譲る -->
  <article>
    <img src="/thumb/post-1.webp" alt="" width="400" height="225"
         loading="lazy" fetchpriority="low">
  </article>
  <article>
    <img src="/thumb/post-2.webp" alt="" width="400" height="225"
         loading="lazy" fetchpriority="low">
  </article>
</section>

<footer>
  <img src="/badges/partner.svg" alt="" width="120" height="40"
       fetchpriority="low" loading="lazy">
</footer>

loading="lazy"はビューポート付近まで読み込みを遅延する。fetchpriority="low"は読み込みが開始される際の優先度を下げる。併用して相補的に使える。

手法 効果
fetchpriority=high LCP候補の取得開始と帯域配分を前倒し
fetchpriority=low 非クリティカル画像の優先度を下げ、LCPへの帯域譲渡
loading=lazy ビューポート外までリクエスト自体を遅延
preload (LCP) HTMLパース前からLCP画像のダウンロード開始
preconnect CDNオリジンへの接続確立を前倒し(画像URLホストに対して)

<link><script>・背景画像への拡張

fetchpriorityはimg専用ではない。CSS背景のLCPは要素として計測されにくいため、LCPがbackground-imageの場合は<img>への置き換えを先に検討する(web.devも<img>推奨)。

<head>
  <!-- CDNへ早期接続(HTTP/2・HTTP/3の効果と相乗) -->
  <link rel="preconnect" href="https://cdn.example.com" crossorigin>

  <!-- LCP WebP -->
  <link rel="preload" as="image" href="https://cdn.example.com/hero.webp"
        fetchpriority="high">

  <!-- クリティカルフォント(LCPがテキストの場合) -->
  <link rel="preload" as="font" type="font/woff2"
        href="/fonts/noto-sans-jp-subset.woff2" crossorigin
        fetchpriority="high">

  <!-- 次ページ用の prefetch は low -->
  <link rel="prefetch" href="/next-page/" fetchpriority="low">
</head>

scriptへの適用(慎重に)

<!-- 計測タグは async + low でLCPと競合しない -->
<script src="https://www.googletagmanager.com/gtag/js?id=G-XXXX" async fetchpriority="low"></script>

<!-- アプリ本体は defer(fetchpriority省略で十分なことが多い) -->
<script src="/js/bundle.js" defer></script>

同期scriptにhighを付けても、パーサーブロッキングは解消しない。LCP改善の主戦場は画像とCSSに留めるのが安全だ。

JavaScriptで動的にfetchpriorityを制御する

SPAやCMS連携で、クライアント側からLCP候補を切り替える場合のパターン。

ルートロード時にヒーロー画像を注入

/**
 * LCP候補のヒーローURLをAPIから取得した後にimgを差し込む場合、
 * 可能な限りSSR/SSGで最初からHTMLに含めるのが理想。
 * やむを得ずクライアント注入する場合の例。
 */
async function injectHeroImage(container, apiUrl) {
  const data = await fetch(apiUrl, { priority: 'high' }).then((r) => r.json());
  const heroUrl = data.heroImageUrl;
  const srcset = data.heroSrcset || '';

  const link = document.createElement('link');
  link.rel = 'preload';
  link.as = 'image';
  link.href = heroUrl;
  link.fetchPriority = 'high';
  if (srcset) {
    link.imageSrcset = srcset;
    link.imageSizes = '100vw';
  }
  document.head.appendChild(link);

  const img = document.createElement('img');
  img.src = heroUrl;
  img.alt = data.heroAlt || '';
  img.width = 1200;
  img.height = 630;
  img.fetchPriority = 'high';
  img.decoding = 'async';
  img.className = 'hero';
  if (srcset) {
    img.srcset = srcset;
    img.sizes = '100vw';
  }

  container.replaceChildren(img);
}

document.addEventListener('DOMContentLoaded', () => {
  const root = document.getElementById('hero-root');
  if (root) injectHeroImage(root, '/api/hero');
});

Fetch APIにもpriority: 'high' | 'low' | 'auto'がある(RequestInit)。XHRには無い。LCPに直結するJSONより、画像preloadの方が優先されるべきだ。

Intersection Observerとlowの組み合わせ

/**
 * カルーセル: 表示スライドのみ auto/high、それ以外は low
 */
function initCarouselPriority(carouselEl) {
  const slides = carouselEl.querySelectorAll('[data-slide-image]');

  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        const img = entry.target;
        if (!(img instanceof HTMLImageElement)) return;

        if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
          img.fetchPriority = 'high';
          img.loading = 'eager';
        } else {
          img.fetchPriority = 'low';
        }
      });
    },
    { root: carouselEl, threshold: [0, 0.5, 1] }
  );

  slides.forEach((slide, index) => {
    const img = slide.querySelector('img');
    if (!img) return;
    img.fetchPriority = index === 0 ? 'high' : 'low';
    observer.observe(img);
  });
}

document.querySelectorAll('[data-carousel]').forEach(initCarouselPriority);

最初のスライドだけhigh、残りはlow——動的UIでも帯域の「松と竹」をコードで表現できる。

フレームワーク別実装 — React / Next.js / Astro

React(JSX)

export function Hero({ src, srcSet, sizes, alt }) {
  return (
    <img
      src={src}
      srcSet={srcSet}
      sizes={sizes}
      alt={alt}
      width={1200}
      height={630}
      fetchPriority="high"
      decoding="async"
      className="hero-image"
    />
  );
}

export function ArticleThumbnail({ src, alt, priority = false }) {
  return (
    <img
      src={src}
      alt={alt}
      width={400}
      height={225}
      loading={priority ? 'eager' : 'lazy'}
      fetchPriority={priority ? 'auto' : 'low'}
    />
  );
}

React 18.2+ / 19ではfetchPriority(camelCase)がDOMプロパティとしてサポートされる。Next.js App Routerの<Image priority />は内部でpreload + 高優先度相当の処理を行う。

Next.js App Router

import Image from 'next/image';

export default function HomePage() {
  return (
    <main>
      {/* priority=true → preload + eager + 高優先度 */}
      <Image
        src="/hero.webp"
        alt="ヒーロー"
        width={1200}
        height={630}
        priority
        sizes="100vw"
        style={{ width: '100%', height: 'auto' }}
      />

      <Image
        src="/gallery-1.webp"
        alt="ギャラリー"
        width={400}
        height={300}
        loading="lazy"
        fetchPriority="low"
      />
    </main>
  );
}

priority propは1ページに少数に抑える。Next.jsドキュメントもLCP要素1つを推奨している。

Astro

---
// src/components/Hero.astro
const { src, alt, width, height } = Astro.props;
---
<link rel="preload" as="image" href={src} fetchpriority="high" />

<img
  src={src}
  alt={alt}
  width={width}
  height={height}
  fetchpriority="high"
  decoding="async"
  loading="eager"
/>

Astroの<Image />コンポーネントを使う場合はloading="eager"と適切なwidth/heightを指定し、LCP候補にはビルド時preloadが注入される設定(preloadオプション)を確認する。

HTTP/2・HTTP/3との関係

fetchpriorityは同一オリジン(または同一接続)内のストリーム優先度を調整する。传输层がHTTP/2やHTTP/3であれば、複数リソースの並列ダウンロード中に「どのストリームを先に処理するか」にヒントが効く。

HTTP/1.1では接続数制限(通常6並列)が支配的で、fetchpriority単体の効果は相対的に小さいことがある。CDNでHTTP/3を有効化し、preconnectで接続確立を短縮したうえでfetchpriorityを使うと、TTFB + ストリーム優先度の両方を最適化できる。

4200
最適化前 LCP: 4200
最適化前 LCP
3600
+ HTTP/2 CDN: 3600
+ HTTP/2 CDN
2800
+ preload hero: 2800
+ preload hero
2400
+ fetchpriority: 2400
+ fetchpriority

上記は同一ページでの段階改善イメージ(ミリ秒)。環境により差は大きいが、転送層 → preload → fetchpriorityの順で積み上がる典型パターンを示す。

web.dev ベストプラクティスまとめ(2026)

Google web.devおよびChrome Developersが推奨するLCP画像最適化チェックリストを、fetchpriorityの観点で整理する。

  1. LCP要素を<img>で配信 — CSS background-imageよりマークアップ画像
  2. 発見可能(Discoverable) — HTMLソースまたはpreloadで早期にURLが分かる
  3. 適切なサイズ — srcset/sizes、AVIF/WebP、レスポンシブ
  4. 遅延加载禁止 — LCP imgにloading="lazy"を付けない
  5. fetchpriority=high — LCP候補1つ
  6. preload<head>内、パース前開始が必要な場合
  7. CDN + HTTP/2/3 — 接続効率とエッジキャッシュ
  8. CLS対策 — width/heightまたはaspect-ratio
1

[object Object]

2

[object Object]

3

[object Object]

4

[object Object]

5

[object Object]

6

[object Object]

よくあるアンチパターン

アンチパターン結果
全imgにfetchpriority="high"優先度 flatten、効果なし
LCP imgにloading="lazy"意図的遅延でLCP大幅悪化
preload URLとimg srcの不一致二重ダウンロード
CSS背景のみのヒーローLCP計測・preloadが困難
fetchpriorityのみで500KB PNGのままLoad time支配、総合改善小

レスポンシブ画像とfetchpriority

srcset/sizesとpreload属性の整合が、2026年の実装で最もミスが多い。

<head>
  <link rel="preload" as="image"
        imagesrcset="
          /hero-640.webp 640w,
          /hero-1280.webp 1280w,
          /hero-1920.webp 1920w
        "
        imagesizes="(max-width: 768px) 100vw, 1280px"
        fetchpriority="high">
</head>
<body>
  <picture>
    <source type="image/avif"
            srcset="/hero-640.avif 640w, /hero-1280.avif 1280w"
            sizes="(max-width: 768px) 100vw, 1280px">
    <source type="image/webp"
            srcset="/hero-640.webp 640w, /hero-1280.webp 1280w"
            sizes="(max-width: 768px) 100vw, 1280px">
    <img src="/hero-1280.webp"
         alt="商品メインビジュアル"
         width="1280"
         height="720"
         fetchpriority="high"
         decoding="async">
  </picture>
</body>

<picture>でAVIFとWebPを併用する場合、preloadはブラウザが実際に選ぶ形式とURLに合わせる必要がある。複雑な場合は単一形式(WebP)に preload を合わせるか、CriticalなLCPだけ<picture>をやめて単一<img srcset>に統一する判断もある。

<video poster> と LCP

動画ヒーローのLCPはposter画像になることが多い。

<video
  autoplay
  muted
  loop
  playsinline
  poster="/video/hero-poster.webp"
  width="1280"
  height="720"
  fetchpriority="high"
>
  <source src="/video/hero.webm" type="video/webm">
  <source src="/video/hero.mp4" type="video/mp4">
</video>

<link rel="preload" as="image" href="/video/hero-poster.webp" fetchpriority="high">

動画本体(as=video preload)は帯域を食いLCP posterと競合しうる。posterを先に、動画はpreload="none"またはIntersection後加载が安全。

計測用スクリプト — LCPとリソースの対応付け

Fieldに近い形でLCP要素とリソースURLをログするPerformanceObserver例。

/**
 * 本番でも軽量にLCP候補を analytics へ送る例
 * (個人情報に注意し、URLのみ送信)
 */
(function observeLcpForPriorityAudit() {
  if (!('PerformanceObserver' in window)) return;

  const observer = new PerformanceObserver((list) => {
    const entries = list.getEntries();
    const last = entries[entries.length - 1];
    if (!last) return;

    const el = last.element;
    let resourceUrl = '';

    if (el instanceof HTMLImageElement) {
      resourceUrl = el.currentSrc || el.src;
    } else if (el instanceof HTMLVideoElement) {
      resourceUrl = el.poster || '';
    }

    const payload = {
      metric: 'LCP',
      value: Math.round(last.startTime),
      resourceUrl,
      fetchPriority: el && 'fetchPriority' in el ? el.fetchPriority : 'n/a',
      id: last.id,
    };

    if (navigator.sendBeacon) {
      navigator.sendBeacon('/analytics/vitals', JSON.stringify(payload));
    } else {
      console.info('[LCP audit]', payload);
    }

    observer.disconnect();
  });

  observer.observe({ type: 'largest-contentful-paint', buffered: true });
})();

fetchPriorityhighなのにLCPが遅い場合、Load delayではなくTTFBや画像サイズを疑う。逆にautoのまま良好なら、無理にhighを増やさない。

DevTools Network — Priority列の読み方

Networkパネルで画像リクエストを選び、Priority列を表示する(右クリック → Priority)。

表示意味(Chrome)
Highest通常 preload + high
Highfetchpriority=high の img 等
Mediumデフォルトの img / script
Lowfetchpriority=low
Lowestprefetch 等

Initiatorが(index)や行番号付きHTMLならパース後発見。preloadならhead内ディレクティブ経由——Start Timeが早いはずだ。改善後もLCP画像のStartが遅い場合、CSS/同期JSのブロッキングをCRP記事の手順で削る。

Priority列が gray のとき

キャッシュ(memory cache / disk cache)ヒット時はPriority表示が異なることがある。Cold cache + Disable cache OFF(通常リロード)で計測する。Before/After比較は同じキャッシュ条件で揃える。

セキュリティ・プライバシー上の注意

fetchpriority自体にセキュリティリスクはないが、高優先度で取得するURLにPIIを含めない(例: 署名付きURLのクエリ)。preloadは他ページへの/navigate前には効かない——現在ドキュメント専用。

CSP(Content-Security-Policy)でimg-srcが制限されている場合、preload URLも同一ポリシー内である必要がある。違反するとコンソールエラーとともにpreloadが無視される。

チェックリスト — リリース前の最終確認

1

Performance Insights で LCP 要素が想定どおりか確認

2

LCP img に lazy が付いていないか grep

3

fetchpriority=high が2件以下か確認

4

preload の imagesrcset/imagesizes が img と一致しているか

5

width/height で CLS が 0.1 未満か

6

Below-the-fold 画像に low + lazy を適用したか

7

Network で LCP リクエストの Priority が High 以上か

8

Lighthouse LCP が 2.5s 以下(モバイルシミュレーション)か

関連記事

この記事は Webパフォーマンス テーマの一環です。あわせて読むと理解が深まる関連記事をまとめました。

トピック記事
Speculation Rules API 完全ガイドSpeculation Rules API 完全ガイド|prefetch・prerender・Chrome 144 prerender_until_script
Web Vitals INP改善ガイドWeb Vitals INP改善ガイド|scheduler.yield・Long Task・Input Delay対策(2026)
content-visibility: auto 完全ガイドcontent-visibility: auto 完全ガイド|遅延レンダリングと長尺ページ最適化 2026
Server-Timing API 完全ガイドServer-Timing API 完全ガイド|Express ミドルウェアと Chrome DevTools 連携
Brotli vs Gzip 圧縮比較Brotli vs Gzip 圧縮比較|nginx静的・動的設定とCDN実践ガイド
CSS/JSを圧縮(Minify)するメリットCSS/JSを圧縮(Minify)するメリット|サイト高速化の基本
Service Worker キャッシュ戦略ガイドService Worker キャッシュ戦略ガイド|PWA の cache-first・network-first・SWR・Workbox 設計
View Transitions API 完全ガイドView Transitions API 完全ガイド|SPA・MPA ページ遷移と Astro/React 統合
WebP変換で画質が落ちる原因と最適な設定WebP変換で画質が落ちる原因と最適な設定
画像圧縮とWebP変換画像圧縮とWebP変換|PageSpeed改善の基本
Image Compress WebPImage Compress WebP|画質とサイズのバランス
HSTS Preload設定手順HSTS Preload設定手順|nginx・Cloudflare実装とhstspreload.org申請ガイド

まとめ

fetchpriorityは、2026年のWebパフォーマンス最適化において、LCP画像の「帯域競合」を解くための低コスト・高ROIのHTML属性だ。highはLCP候補1つに、lowはそれ以外の装飾やサムネイルに。preloadと併用し、Performance InsightsとNetworkのPriority列で検証する。

転送層はHTTP/2・HTTP/3で整え、描画経路はクリティカルレンダリングパスで短くし、fetchpriorityで同一ページ内の最後の優先度調整を行う——この3層でLCP 2.5秒以内を現実的な目標にできる。

次の一手

LCP改善後もINP(Interaction to Next Paint)が課題なら、メインスレッド長タスクの分割やSSR hydrationの見直しへ。画像優先度とJS実行のバランスが、2026年のCore Web Vitals全体最適化の鍵になる。