🌊
AstroのPictureコンポーネントを自作した
最近プロジェクトでAstroを使っていて、画像の最適化で色々調査して結果的に自作することになりました。
実現したいこと
スクラップの記事にも書いたのですが、
- 画像の最適化をしたい。(jpgやpngをwebpに変換してほしい)
- pictureタグで画面幅に合わせて画像を出し分けしたい。
<picture>
<source srcset="画像のパス" media="(min-width: 1024px)">
<img src="画像のパス" alt=”代替テキスト”>
</picture>
- 背景画像も最適化の対象としたい。
- ビルド時に最適化処理したい。
- 画像ディレクトリは一緒にしたい。
Astro公式のPictureコンポーネント
Astro v4.2時点ではImage
コンポーネントとPicture
コンポーネントが定義されているが、背景画像や画面幅での出しわけができない。
自作したPictureコンポーネント
getImage関数を使って画像を最適化しています。
MIN_WIDTH_MDは"(min-width: 960px)";
を定数として定義しているものです。
pngやjpgのフォールバックはありませんが、渡ってきたpropsには入っていますので必要であれば対応できます。
---
import { getImage } from 'astro:assets';
import type { HTMLAttributes } from 'astro/types';
import { MIN_WIDTH_MD } from '~/data/siteData';
interface Props extends HTMLAttributes<'img'> {
imgSrc: ImageMetadata;
imgSrcPC?: ImageMetadata;
}
const { imgSrc, imgSrcPC, ...attrs } = Astro.props;
const optimizedImage = await getImage({ src: imgSrc, format: 'webp' });
const optimizedPCImage = imgSrcPC && (await getImage({ src: imgSrcPC, format: 'webp' }));
---
<picture>
{imgSrcPC && <source media={MIN_WIDTH_MD} srcset={optimizedPCImage?.src} />}
<img src={optimizedImage.src} {...attrs} />
</picture>
こんな感じで使います。
---
import Picture from '~/components/atomic/Picture.astro';
import largeImage from '~/images/imgpc.png';
import smallImage from '~/images/img.png';
---
<Picture imgSrc={smallImage} imgSrcPC={largeImage} alt="" />
この勢いで背景画像もどうにかできないか模索していきます。
Discussion