6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要

Astro 5.10でImageコンポーネントがアップデートされ、Responsive imagesという機能が正式に使えるようになりました。

ビルド時に複数サイズの画像を書き出して、自動でsrcsetを付与するなどで画像を最適化する仕組みです。
要はNext.jsのImageコンポーネントと同じです。

理屈で言えばパフォーマンスが上がるんだとは思いますが、どれくらい効果があるのかが知りたかったので簡単に調べてみました。

この記事で示す改善率や数値は、今回のテスト環境・テスト内容に基づく結果であり、すべての環境やサイトでの効果を保証するものではありません。実際の効果は、サイトの構成、画像の種類、ユーザーの環境などによって大きく異なる可能性があります。

対象読者

  • Astroを使用している中で
    • まだResponsive imagesを導入できていない人
    • 自分のプロジェクトで導入すると良いか考えている人

結論

現代的な大抵のページはResponsive imagesを適用した方がパフォーマンスは上がりそうです。
ただし、トレードオフを理解した上で導入を検討する必要があります。

  • 明確にパフォーマンスが改善されたケース:
    • レスポンシブレイアウトを多用するページ(33%のLCP改善)
    • 複雑なコンテンツが混在するページ(15%のLCP改善)
  • 注意すべき点:
    • ビルド時間やビルドサイズは大幅に増加する(138%増加)
    • ページの構成次第ではFCPが悪化することもある(44%悪化のケースあり)

Astro 5.10での設定変更

Responsive imagesを有効にするには、astro.config.mjsで以下の設定を行います:

astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  image: {
    responsiveStyles: true, // レスポンシブ画像機能を有効化
    layout: 'constrained', // 'constrained' | 'full-width' | 'fixed' | 'none'
  },
});

なお、個別画像ごとに設定することもできますが今回は省略します。

設定オプション

  • responsiveStyles:
    • trueに設定すると、自動的にsrcsetとsizesが生成される
  • layoutオプション:
    • constrained: 画像はアスペクト比を維持しながらコンテナに収まるようにスケールダウンする
    • full-width: 画像はアスペクト比を維持しながら、コンテナの幅に合わせてスケールする
    • fixed: 画像は要求された寸法を維持し、リサイズしない
    • none: 画像はレスポンシブにならない

測定方法

見た目やコンテンツ数はまったく同じページをAstro 5.9と5.10で用意して、パフォーマンス測定スクリプトを走らせます。

測定環境の構築

今回は5つのタイプのテストページを用意しました。
すべてAIで生成しています。

ページ種別 スクリーンショット
シンプルなランディングページ風 index.png
大きなヒーロー画像を使用したページ hero.png
12枚の画像グリッドページ grid.png
ヒーロー画像とコンテンツ画像が混在するページ mixed.png
レスポンシブデザイン用ページ responsive.png

テスト用画像の生成で気をつけたこと

画像最適化の効果を正確に測定するため、以下の点を考慮して画像を生成しました:

  • サイズのバリエーション: ヒーロー画像(1920x1080)、コンテンツ画像(800x600/600x800/800x800)、サムネイル(300x200)など、実際のWebサイトで使用されそうな様々なサイズを設定
  • ファイル形式のバリエーション: JPEG、PNG、WebP形式を混在させ、それぞれの最適化効果を測定
  • ファイル容量のバリエーション: 3KB〜1MB近い画像まで、色々なサイズのものを用意
  • 画像内容の工夫:
    • グラデーション系画像(圧縮効率が高い)
    • 複雑なテクスチャ画像(圧縮効率が低い)
    • 透明度を含むPNG画像

このように、実際のWebサイトで遭遇する様々な画像パターンを網羅することで、より現実的なパフォーマンス測定を目指しました。

測定スクリプトの概要

PlaywrightとChromeのパフォーマンスAPIを使用して、以下のメトリクスを測定しました。

// 各ページに対して3回ずつ測定を実行
const TEST_RUNS = 3;

// 測定するCore Web Vitals
const metrics = {
  lcp: null,  // Largest Contentful Paint
  fcp: null,  // First Contentful Paint
  cls: null,  // Cumulative Layout Shift
};

また、測定や分析にあたって以下に気をつけています。

  • 各実行で新しいブラウザインスタンスを作成(コールドスタート)
  • キャッシュを完全に無効化
  • 画像の完全な読み込み完了を待機
  • 外れ値を除去した統計処理

Core Web Vitalsの測定:

// LCP測定
const lcpObserver = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];
  lcpValue = Math.round(lastEntry.startTime);
});
lcpObserver.observe({ type: "largest-contentful-paint", buffered: true });

PerformanceObserver APIについて

PerformanceObserver APIは、ブラウザが実際に計測するパフォーマンス指標をリアルタイムで取得できるWeb標準のAPIです。今回の測定では、以下の指標を取得しています:

  • LCP (Largest Contentful Paint): ページの主要コンテンツが描画完了した時刻
  • FCP (First Contentful Paint): 最初のコンテンツが描画された時刻
  • CLS (Cumulative Layout Shift): レイアウトのずれの累積値

new Date()などではなくこのAPIを使用することで、ChromeのLighthouseやPageSpeed Insightsと同等の信頼性の高い測定が可能になります。

測定結果

ランタイムパフォーマンス比較(3回測定の平均値)

ページタイプ メトリクス Astro 5.9 Astro 5.10 改善率
シンプルなランディングページ風 LCP 95ms 89ms +6%
FCP 95ms 89ms +6%
大きなヒーロー画像を使用したページ LCP 188ms 185ms +2%
FCP 59ms 85ms -44%
12枚の画像グリッドページ LCP 77ms 79ms -3%
FCP 63ms 64ms -2%
ヒーロー画像とコンテンツ画像が混在するページ LCP 192ms 164ms +15%
FCP 68ms 65ms +4%
レスポンシブデザイン用ページ LCP 195ms 131ms +33%
FCP 69ms 72ms -4%

(なお、CLSはどれも0でした)

ビルド出力の比較

項目 Astro 5.9 Astro 5.10 変化率
総ビルドサイズ 385.79KB 921.32KB +138.81%
画像ファイル数 25ファイル 58ファイル +132%
画像総サイズ 348.63KB 873.78KB +150.63%
HTMLサイズ 37.16KB 47.54KB +27.94%

結果から分かること

測定で確認できたこと

  • パフォーマンス改善が顕著なケース:
    • レスポンシブレイアウトページでLCPが33%改善(195ms → 131ms)
    • 複雑なコンテンツページでLCPが15%改善(192ms → 164ms)
    • シンプルなページでも6%の改善
  • パフォーマンスが悪化したケース:
    • ヒーロー画像ページでFCPが44%悪化(59ms → 85ms)
    • ギャラリーページで軽微な悪化
  • ビルド時の変化:
    • 画像ファイルが2.3倍に増加(自動生成される複数サイズバリエーション)
    • 総ビルドサイズが約2.4倍に増加
    • HTMLファイルサイズが約30%増加(srcset属性の追加)

なぜこのような結果になったのか

  • LCP改善の理由:
    • ブラウザが最適なサイズの画像を自動選択
    • 不要に大きな画像のダウンロードを回避
    • 特にレスポンシブデザインで効果が大きい
  • FCP悪化の理由(推測):
    • srcsetの画像選択処理によるオーバーヘッド?
    • 複数の画像候補から最適なものを選ぶ処理時間?
    • シンプルな構成では従来の最適化の方が有利な場合があるらしい
  • ビルドサイズ増加の理由:
    • 各画像に対して複数のサイズバリエーションを自動生成
    • WebP形式での最適化バージョンも追加生成
    • レスポンシブ対応のためのメタデータ増加

実用的な判断基準

  • Responsive imagesを導入すべきケース:
    • レスポンシブデザインが重要なサイト
    • 多様なデバイスからのアクセスが想定される
    • 複雑なレイアウトのコンテンツページが多い
    • ビルドサイズの増加を許容できる環境
  • 従来の手動最適化を継続すべきケース:
    • シンプルなヒーロー画像中心のページ
    • ビルドサイズやビルド時間に厳しい制約がある

測定結果から、Astro 5.10のResponsive imagesはパフォーマンス改善をもたらすものの、すべてのケースで有効というわけでもないようです。

自分のプロジェクトの特性やページごとの特性を考慮して導入してみてください。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?