Astro は静的サイト生成に優れたフレームワークで、特にパフォーマンスを重視した最適化機能が特徴です。その中でも Image と Picture コンポーネントは、画像の最適化とレスポンシブ対応に不可欠なツールです。このガイドでは、両コンポーネントの使用法、パフォーマンス、SEO への影響、そしてそれぞれの詳細な使い分けについて説明します。
この記事で学べること
- Image と Picture コンポーネントの基本的な使い方
- ローカル画像とリモート画像の取り扱い
- レスポンシブ画像の実装方法
- パフォーマンスとSEOを考慮した最適化手法
- 両コンポーネントの使い分け
共通点と基礎
インポート方法
両コンポーネントは astro:assets パッケージからインポートされ、画像の最適化と管理を行います。
---
import { Image, Picture } from 'astro:assets';
---
Astro の標準機能として提供されているため、セットアップはシンプルで、プロジェクトにインストールする追加のライブラリは必要ありません。
主要な目的
両コンポーネントの主な目的は以下の通りです。
| 目的 | 説明 |
|---|---|
| 画像の最適化 | ファイルサイズの縮小により、ページの読み込み時間を短縮 |
| レスポンシブ画像の提供 | 異なる画面サイズに応じて適切な画像を提供 |
| 遅延読み込みのサポート | lazy ロードにより、ページの表示速度を最適化 |
| CLS の軽減 | width/height の自動設定でレイアウトシフトを防止 |
主要な属性
どちらのコンポーネントも以下のような共通の属性を使用します。
| 属性 | 説明 | 必須 |
|---|---|---|
src | 画像のソース(ローカルまたはリモートURL) | ✓ |
alt | 画像の代替テキスト(アクセシビリティ用) | ✓ |
width | 画像の幅(リモート画像では必須) | △ |
height | 画像の高さ(リモート画像では必須) | △ |
loading | 読み込みタイミング("lazy" または "eager") | - |
decoding | デコード方法("async", "sync", "auto") | - |
Image コンポーネント
基本的な使用方法
Image コンポーネントは、単一の最適化された画像を提供するシンプルなコンポーネントです。
---
import { Image } from 'astro:assets';
import myImage from '../assets/hero.png';
---
<Image src={myImage} alt="ヒーロー画像" />
特徴
- 自動サイズ設定: ローカル画像の場合、
Astroはビルド時にwidthとheightを自動的に設定します。つまり、ローカルファイルを参照するときにはwidthとheightの設定は不要となります。ただし、ローカルでもpublic内の画像は対象とならないので注意しましょう。 - フォーマット変換: 必要に応じて画像フォーマットを自動的に変換します。
- 単一の画像提供: このコンポーネントは、単一の最適化された画像を生成し、出力します。
最適化オプション
Image コンポーネントにはフォーマットや画質を指定するオプションがあります。
| オプション | 説明 | 値の例 |
|---|---|---|
format | 出力フォーマット | "webp", "avif", "png", "jpeg" |
quality | 出力品質(0-100) | 80 |
densities | ピクセル密度の配列 | [1, 2] |
ローカル画像の使用例
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<!-- 基本的な使用 -->
<Image src={heroImage} alt="ヒーロー画像" />
<!-- フォーマットと品質を指定 -->
<Image
src={heroImage}
alt="最適化されたヒーロー画像"
format="webp"
quality={80}
/>
<!-- Retinaディスプレイ対応 -->
<Image
src={heroImage}
alt="高解像度対応画像"
densities={[1, 2]}
/>
リモート画像の使用例
リモート画像を使用する場合は、width と height を必ず指定する必要があります。
---
import { Image } from 'astro:assets';
---
<Image
src="https://example.com/image.jpg"
alt="リモート画像"
width={800}
height={600}
format="webp"
/>
リモート画像の許可設定
リモート画像を使用するには、astro.config.mjs で許可するドメインを設定します。
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
image: {
domains: ['example.com', 'images.unsplash.com'],
// または、すべてのリモート画像を許可
// remotePatterns: [{ protocol: 'https' }],
},
});
適用範囲と制約
単一の画像を使用する場合に最適で、特に複雑なレスポンシブ対応やフォーマット切り替えの必要がない場合に向いています。フォーマット指定をしない場合は、Astro が最適な形式で画像を生成しますが、特定のニーズがある場合は手動で設定する必要があります。
Picture コンポーネント
基本的な使用方法
Picture コンポーネントは、複数の画像フォーマットや解像度を提供し、レスポンシブ対応を可能にします。
---
import { Picture } from 'astro:assets';
import myImage from '../assets/hero.png';
---
<Picture
src={myImage}
alt="レスポンシブ画像"
widths={[400, 800, 1200]}
sizes="(max-width: 800px) 100vw, 800px"
/>
特徴
| 特徴 | 説明 |
|---|---|
| 複数のフォーマット | WebP、AVIF、JPEG などを同時に生成し、ブラウザが最適なものを選択 |
| 複数の解像度 | デバイスや画面サイズに応じて異なる解像度の画像を提供 |
| アートディレクション | デバイスに応じて異なる画像(トリミング違いなど)を提供可能 |
追加の属性
| 属性 | 説明 | 例 |
|---|---|---|
widths | 生成する画像幅の配列 | [400, 800, 1200] |
sizes | レスポンシブサイズ指定 | "(max-width: 800px) 100vw, 800px" |
formats | 出力フォーマットの配列 | ['avif', 'webp', 'jpeg'] |
fallbackFormat | フォールバック用フォーマット | "jpeg" |
使用例:複数フォーマットと解像度
---
import { Picture } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<Picture
src={heroImage}
alt="レスポンシブ画像"
widths={[400, 800, 1200, 1600]}
sizes="(max-width: 640px) 100vw, (max-width: 1024px) 80vw, 1200px"
formats={['avif', 'webp', 'jpeg']}
/>
この例では、以下が生成されます:
- 4つの解像度(400px, 800px, 1200px, 1600px)
- 3つのフォーマット(AVIF, WebP, JPEG)
- 合計12枚の最適化された画像
アートディレクションとメディアクエリ
Picture コンポーネントは、アートディレクションにも利用できます。以下の例では、特定の画面サイズに応じて異なる画像が表示されます。
---
import { Picture } from 'astro:assets';
import desktopImage from '../assets/hero-desktop.jpg';
import mobileImage from '../assets/hero-mobile.jpg';
---
<Picture
src={desktopImage}
alt="レスポンシブ画像"
widths={[800, 1200, 1600]}
sizes="(max-width: 800px) 100vw, 800px"
formats={['avif', 'webp', 'jpeg']}
>
<source
media="(max-width: 640px)"
srcset={mobileImage.src}
/>
</Picture>
このアプローチにより、モバイルユーザーには小さな画像、デスクトップユーザーには大きな画像が提供されます。
適用範囲と制約
複数の解像度やフォーマットを使いたい場合に最適です。フォーマットや解像度が多くなるほど、ビルド時間とストレージ使用量が増加します。
主な違い
生成される HTML
Image コンポーネント
<img
src="/_astro/hero.abc123.webp"
alt="説明"
width="800"
height="600"
loading="lazy"
decoding="async"
/>
Picture コンポーネント
<picture>
<source type="image/avif" srcset="/_astro/hero.400.avif 400w, /_astro/hero.800.avif 800w" sizes="..." />
<source type="image/webp" srcset="/_astro/hero.400.webp 400w, /_astro/hero.800.webp 800w" sizes="..." />
<img src="/_astro/hero.800.jpeg" alt="説明" width="800" height="600" loading="lazy" decoding="async" />
</picture>
比較表
| 項目 | Image | Picture |
|---|---|---|
| 生成されるタグ | <img> | <picture> + <source> + <img> |
| フォーマット | 単一 | 複数対応 |
| 解像度 | 単一(densities対応可) | 複数対応 |
| アートディレクション | 非対応 | 対応 |
| ビルド時間 | 短い | 長くなる可能性 |
| 使用シナリオ | シンプルな画像表示 | 高度なレスポンシブ対応 |
使い分けガイド
画像を表示したい
│
├─ 複数のフォーマットが必要?
│ ├─ Yes → Picture
│ └─ No ─┐
│ │
├─ 複数の解像度が必要?
│ ├─ Yes → Picture
│ └─ No ─┐
│ │
├─ アートディレクションが必要?
│ ├─ Yes → Picture
│ └─ No → Image
実践的なコード例
ブログカードの画像
---
import { Image } from 'astro:assets';
interface Props {
title: string;
image: ImageMetadata;
href: string;
}
const { title, image, href } = Astro.props;
---
<article class="blog-card">
<a href={href}>
<Image
src={image}
alt={title}
width={400}
height={225}
format="webp"
quality={80}
class="card-image"
/>
<h3>{title}</h3>
</a>
</article>
<style>
.blog-card {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.card-image {
width: 100%;
height: auto;
object-fit: cover;
}
</style>
ヒーローセクションの背景画像
---
import { Picture } from 'astro:assets';
import heroDesktop from '../assets/hero-desktop.jpg';
import heroMobile from '../assets/hero-mobile.jpg';
---
<section class="hero">
<Picture
src={heroDesktop}
alt=""
widths={[640, 1024, 1440, 1920]}
sizes="100vw"
formats={['avif', 'webp', 'jpeg']}
class="hero-image"
>
<source
media="(max-width: 768px)"
srcset={heroMobile.src}
/>
</Picture>
<div class="hero-content">
<h1>Welcome to Our Site</h1>
<p>素晴らしい体験をお届けします</p>
</div>
</section>
<style>
.hero {
position: relative;
height: 80vh;
overflow: hidden;
}
.hero-image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.hero-content {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
color: white;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}
</style>
画像ギャラリー
---
import { Image } from 'astro:assets';
// 画像をまとめてインポート
const images = await Astro.glob('../assets/gallery/*.{jpg,png,webp}');
---
<div class="gallery">
{images.map((image, index) => (
<figure class="gallery-item">
<Image
src={image.default}
alt={`ギャラリー画像 ${index + 1}`}
width={300}
height={300}
format="webp"
quality={75}
class="gallery-image"
/>
</figure>
))}
</div>
<style>
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
}
.gallery-item {
margin: 0;
overflow: hidden;
border-radius: 8px;
}
.gallery-image {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.gallery-image:hover {
transform: scale(1.05);
}
</style>
パフォーマンスと SEO への影響
画像最適化
両コンポーネントは画像を最適化し、ファイルサイズを削減することで、ページ読み込み速度を向上させます。最適化された画像は、より速く読み込まれるため、ユーザー体験が向上します。
Cumulative Layout Shift (CLS)の軽減
width と height を指定することで、ページ読み込み時に画像の位置が確保され、レイアウトが崩れることを防ぎます。これにより、CLS が軽減され、Google の Core Web Vitals において良好な評価を得ることができます。
遅延読み込み
loading="lazy" を指定することで、画面外にある画像を遅延して読み込むことができ、初期読み込みのパフォーマンスが向上します。
<!-- ファーストビューの画像は即時読み込み -->
<Image src={heroImage} alt="ヒーロー" loading="eager" />
<!-- それ以外は遅延読み込み(デフォルト) -->
<Image src={contentImage} alt="コンテンツ" loading="lazy" />
画像の発見可能性
SEO の観点から、適切な alt テキストを設定することで、検索エンジンが画像を理解しやすくなり、画像検索のランキングが向上します。
画像フォーマットの影響
次世代フォーマット(WebP や AVIF)を使用することで、画像サイズがさらに圧縮され、パフォーマンスが向上します。
| フォーマット | 圧縮率 | ブラウザ対応 | 用途 |
|---|---|---|---|
| AVIF | 最高 | 新しいブラウザ | 最新環境向け |
| WebP | 高 | ほぼ全ブラウザ | 汎用 |
| JPEG | 中 | 全ブラウザ | フォールバック |
| PNG | 低 | 全ブラウザ | 透過が必要な場合 |
ベストプラクティス
適切な alt テキスト
常に意味のある代替テキストを設定しましょう。これにより、アクセシビリティが向上し、SEO も改善されます。
<!-- 良い例 -->
<Image src={productImage} alt="赤いレザーのハンドバッグ、正面から撮影" />
<!-- 悪い例 -->
<Image src={productImage} alt="画像" />
<Image src={productImage} alt="product-image-001.jpg" />
<!-- 装飾的な画像の場合は空に -->
<Image src={decorativeImage} alt="" />
サイズ最適化
表示サイズに適した width と height を指定し、レイアウトシフトを防ぎます。
<!-- 表示サイズに合わせた指定 -->
<Image
src={thumbnailImage}
alt="サムネイル"
width={150}
height={150}
/>
<!-- アスペクト比を維持してリサイズ -->
<Image
src={largeImage}
alt="リサイズ画像"
width={800}
height={Math.round(800 * (largeImage.height / largeImage.width))}
/>
フォーマット選択
次世代フォーマット(AVIF や WebP)を使用し、画像サイズを最小化しましょう。Picture コンポーネントでは、複数のフォーマットを提供することで、すべてのブラウザに対応することができます。
パフォーマンスを考慮した読み込み
重要でない画像には loading="lazy" を使用し、初期ページロードの速度を向上させましょう。
---
import { Image } from 'astro:assets';
---
<!-- LCP(Largest Contentful Paint)対象の画像 -->
<Image
src={heroImage}
alt="メインビジュアル"
loading="eager"
fetchpriority="high"
/>
<!-- スクロール後に表示される画像 -->
<Image
src={contentImage}
alt="コンテンツ画像"
loading="lazy"
/>
注意点
ビルド時間
大量の画像や複数のフォーマットを生成する場合、ビルド時間が増加する可能性があります。
対策:
Pictureの使用は本当に必要な箇所に限定- 生成する
widthsの数を必要最小限に - 開発時はキャッシュを活用
ストレージ使用量
複数のサイズやフォーマットの画像を生成すると、プロジェクトのストレージ使用量が増加します。
対策:
- フォーマットは2〜3種類に絞る(例:AVIF, WebP, JPEG)
- 解像度は実際に必要なサイズのみ指定
ブラウザ互換性
古いブラウザでは、次世代フォーマット(WebP や AVIF)をサポートしていない場合があります。
対策:
Pictureコンポーネントでフォールバック用の JPEG/PNG を含めるformats配列の最後に互換性の高いフォーマットを指定
<Picture
src={image}
alt="互換性を考慮した画像"
formats={['avif', 'webp', 'jpeg']} <!-- jpegがフォールバック -->
/>
まとめ
このガイドでは、Astro の Image および Picture コンポーネントの詳細な使用方法、パフォーマンス向上、SEO への影響、適切な実装方法について解説しました。
ポイントの振り返り
- Image: シンプルな画像表示に最適。単一フォーマット・解像度
- Picture: 高度なレスポンシブ対応に最適。複数フォーマット・解像度・アートディレクション
- パフォーマンス: 次世代フォーマット + 遅延読み込みで最適化
- SEO: 適切な
altテキストとwidth/heightの指定が重要 - 注意点: ビルド時間とストレージ使用量のバランスを考慮
これらのコンポーネントを適切に活用することで、ウェブサイトのパフォーマンスを最大限に引き出し、ユーザー体験を向上させることができます。