Astro provides powerful image optimization features that automatically handle responsive images, format conversion, compression, and other tasks, significantly improving website performance.
Core Features:
- Automatic Responsive Images: Automatically generates multiple sizes of images
- Format Conversion: Automatically converts to modern image formats (WebP, AVIF)
- Lazy Loading: Automatically implements image lazy loading
- Compression Optimization: Automatically compresses images to reduce file size
Basic Usage:
astro--- import { Image } from 'astro:assets'; import myImage from '../assets/my-image.jpg'; --- <!-- Basic usage --> <Image src={myImage} alt="Description" /> <!-- Specify width and height --> <Image src={myImage} alt="Description" width={800} height={600} /> <!-- Specify format --> <Image src={myImage} alt="Description" format="webp" /> <!-- Specify quality --> <Image src={myImage} alt="Description" quality={80} />
Advanced Configuration:
astro--- import { Image } from 'astro:assets'; import heroImage from '../assets/hero.jpg'; --- <Image src={heroImage} alt="Hero Image" widths={[400, 800, 1200]} sizes="(max-width: 768px) 100vw, 50vw" formats={['avif', 'webp', 'jpeg']} loading="lazy" decoding="async" priority={false} />
Configuration Options Explained:
widths: Generate multiple width versions of the imagesizes: Specify image display size at different screen widthsformats: Specify output formats (by priority)loading: Loading strategy ("eager" or "lazy")decoding: Decoding strategy ("sync" or "async")priority: Whether the image should be loaded with priority
Remote Images:
astro--- import { Image } from 'astro:assets'; import { getImage } from 'astro:assets'; // Process remote images const remoteImage = await getImage({ src: 'https://example.com/image.jpg', alt: 'Remote Image', width: 800, height: 600, format: 'webp', }); --- <img {...remoteImage.attributes} />
Configuring Remote Image Domains:
javascript// astro.config.mjs import { defineConfig } from 'astro/config'; import react from '@astrojs/react'; export default defineConfig({ integrations: [react()], image: { // Allowed remote image domains remotePatterns: [ { protocol: 'https', hostname: 'example.com', }, { protocol: 'https', hostname: '**.cdn.example.com', }, ], }, });
Image Services:
Astro supports multiple image services:
javascript// astro.config.mjs import { defineConfig } from 'astro/config'; import sharp from 'astro/assets/services/sharp'; import imagetools from 'astro/assets/services/imagetools'; export default defineConfig({ image: { // Use Sharp (default, best performance) service: sharp, // Or use ImageTools (more features) // service: imagetools, }, });
Background Images:
astro--- import { Image } from 'astro:assets'; import backgroundImage from '../assets/bg.jpg'; const { src: bgSrc } = await getImage({ src: backgroundImage, format: 'webp', width: 1920, }); --- <div style={`background-image: url('${bgSrc}');`} class="hero-section" > <h1>Hero Section</h1> </div>
Image Gallery Example:
astro--- import { Image } from 'astro:assets'; import { getCollection } from 'astro:content'; const gallery = await getCollection('gallery'); --- <div class="gallery"> {gallery.map(item => ( <figure> <Image src={item.data.image} alt={item.data.title} widths={[300, 600, 900]} sizes="(max-width: 600px) 100vw, 50vw" loading="lazy" /> <figcaption>{item.data.title}</figcaption> </figure> ))} </div> <style> .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; } figure { margin: 0; } img { width: 100%; height: auto; } </style>
Performance Optimization Tips:
-
Use Correct Format Priority:
astro<Image src={image} formats={['avif', 'webp', 'jpeg']} /> -
Reasonable Size Settings:
astro<Image src={image} widths={[400, 800, 1200, 1600]} sizes="(max-width: 768px) 100vw, 50vw" /> -
Prioritize Critical Images:
astro<Image src={heroImage} loading="eager" priority={true} /> -
Lazy Load Non-Critical Images:
astro<Image src={image} loading="lazy" decoding="async" /> -
Control Image Quality:
astro<Image src={image} quality={75} />
Integration with Content Collections:
markdown--- title: "My Article" image: ./hero.jpg --- Article content...
astro--- import { Image } from 'astro:assets'; import { getEntry } from 'astro:content'; const post = await getEntry('blog', 'my-post'); const { image } = post.data; --- <Image src={image} alt={post.data.title} widths={[800, 1200, 1600]} />
Best Practices:
- Use
<Image>component by default instead of<img>tags - Provide meaningful alt text for all images
- Set appropriate loading strategy based on image usage
- Use
widthsandsizesfor true responsiveness - Prioritize modern image formats (AVIF, WebP)
- Configure domain whitelist for remote images
- Process images at build time to avoid runtime overhead
Astro's image optimization features can significantly improve website performance and user experience while maintaining a simple development experience.