Webページで画像を配信するとき、ユーザーのスクリーンサイズに合わせたサイズの画像を配信すればデータ転送量を削減することができ、ページ表示の高速化を期待することができます。
一方で、ユーザーのスクリーンサイズに合わせて事前にサイズの異なる画像を複数用意しておくのは大変です。
しかし、Astroのassets機能を使えば画像幅を複数指定するだけで、フレームワークが自動的にソース画像から指定した幅の画像を生成し、スクリーンサイズに応じて配信画像を切り替えることができるようになります。それだけでなく、画像はWebP形式に変換されるためさらなるパフォーマンス向上も期待することができます。
この記事では、Astroのassets機能を使ってユーザーのスクリーンサイズに合わせたサイズの画像をWebP形式で配信する方法を説明します。
Astroのassets機能の前に、srcsetプロパティについて見てみましょう。
srcsetプロパティはHTML標準で、画像要素 img
タグに対して指定します。その名前の通り複数のソースを指定することができます。
例を見てみましょう。
<img
src="my-image.jpg"
srcset="
my-image.jpg 120w,
my-image@240.jpg 240w
"
sizes="
(max-width: 640px) 120px,
240px
"
alt="Alt text"
/>
上記の例では srcset
にカンマ区切りで my-image.jpg 120w
という値を指定しています。さらに空白区切りで画像パスと幅が指定されています。120w
の w
とは幅記述子で、ピクセル数を表す0でない正の整数を組み合わせて表現されます。
srcset
に幅記述子が指定された場合、sizes
プロパティも指定する必要があります。sizes
プロパティの値はメディアクエリーで記述されます。上記の例では、ウィンドウ幅640pxのサイズポイントを指定していますが、実際に画像がどのように使用されるかはブラウザやユーザーのディスプレイの画素密度に依存します。
srcset
プロパティに幅記述子が使用された場合には src
プロパティの値は候補として使用されません。
一方、幅記述子以外にピクセル密度記述子 x
を用いて srcset
プロパティを記述することもできます。ピクセル密度記述子 x
を使用する場合、src
プロパティの値も候補として考慮され、1x
が省略された場合に src
の値が 1x
として使用されます。
<img
src="my-image.jpg"
srcset="my-image@240.jpg 2x"
alt="Alt text"
/>
srcsetプロパティとsizesプロパティの詳細については下記を参照してください。
前項ではHTML標準のsrcsetプロパティについて説明し、srcsetプロパティを使えばウィンドウ幅に応じた画像ソースが指定できることがわかりました。
しかし、Webサイトにおける画像最適化で一番の問題となるのが、サイズに応じて複数の画像を用意しなければならない点です。
astro:assetsのImageコンポーネントはこの問題を解決してくれます。
まずは一番シンプルなImageコンポーネントの使用例を見てみましょう。
---
import { Image } from 'astro:assets';
import myImage from "../assets/my_image.png"; // Image is 1600x900
---
<Image src={myImage} alt="A description of my image." />
使い方はシンプルで、このように astro:assets
からインポートした Image
コンポーネントの src
に、インポートしたローカル画像をセットするだけです。
これは下記のような img
要素に変換されます。
<img
src="/_astro/my_image.hash.webp"
width="1600"
height="900"
decoding="async"
loading="lazy"
alt="A description of my image."
/>
ポイントは、画像がWebP形式に変換される点と、widthとheightの指定が自動的に追加される点です。つまり、Imageコンポーネントはローカルの画像であればwidthとheightを自動的に取得してくれるということです。
次に、ウィンドウ幅ごとに画像サイズを最適化する例を見てみましょう。
---
import { Image } from 'astro:assets';
import myImage from "../assets/my_image.png"; // Image is 1600x900
---
<Image
src={myImage}
widths={[240, 540, 720, myImage.width]}
sizes={`(max-width: 360px) 240px, (max-width: 720px) 540px, (max-width: 1600px) 720px, ${myImage.width}px`}
alt="A description of my image."
/>
widths
プロパティと sizes
プロパティが追加されています。
widths
プロパティは前項で説明したsrcsetプロパティの幅指定の部分だけになっていることがわかるでしょう。sizes
プロパティはそのままですね。
これは下記のような img
要素に変換されます。
<img
src="/_astro/my_image.hash.webp"
srcset="
/_astro/my_image.hash.webp 240w,
/_astro/my_image.hash.webp 540w,
/_astro/my_image.hash.webp 720w,
/_astro/my_image.hash.webp 1600w
"
sizes="
(max-width: 360px) 240px,
(max-width: 720px) 540px,
(max-width: 1600px) 720px,
1600px
"
alt="A description of my image."
width="1600"
height="900"
loading="lazy"
decoding="async"
/>
前項で説明した srcset
と sizes
プロパティに変換され、それぞれのサイズに合わせた画像も生成されます。つまり、astro:assetsのImageコンポーネントを利用すれば1つのソース画像を用意するだけでウィンドウ幅に合わせた画像の最適化ができるということです。
もちろん、Imageコンポーネントはピクセル密度記述子にも対応しています。
---
import { Image } from 'astro:assets';
import myImage from "../assets/my_image.png";
---
<Image
src={myImage}
width={myImage.width / 2}
densities={[1.5, 2]}
alt="A description of my image."
/>
ピクセル密度記述子を利用するには densities
プロパティを指定します。
これは下記のような img
要素に変換されます。
<img
src="/_astro/my_image.hash.webp"
srcset="
/_astro/my_image.hash.webp 1.5x
/_astro/my_image.hash.webp 2x
"
alt="A description of my image."
width="800"
height="450"
loading="lazy"
decoding="async"
/>
Imageコンポーネントの詳細については下記ドキュメントを参照してください。
以上です。この記事では、Astroのassets機能を使ってユーザーのスクリーンサイズに合わせたサイズの画像をWebP形式で配信する方法を説明しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます