Skip to content

Astro Image Optimization for Web

Astro provides built-in image optimization capabilities through the @astrojs/image integration and the Image component. This document explores how images can be auto-optimized for the web in Astro and Starlight-based sites.

Currently, the site uses markdown images with static file references:

![Nature Landscape](/assets/images/image-generation/1-nature-landscape.png)

These images are served as static files without optimization:

  • No format conversion (WebP/AVIF)
  • No responsive srcset generation
  • No automatic resizing

Astro provides the @astrojs/image package for image optimization:

Terminal window
pnpm add -D @astrojs/image

This integration provides:

  • Format conversion: Automatically converts images to WebP, AVIF, JPEG, PNG
  • Responsive images: Generates srcset attributes for different screen sizes
  • Lazy loading: Native loading="lazy" attribute
  • Aspect ratio preservation: Maintains image proportions

Instead of markdown images, use the Image component:

---
import { Image, getImage } from 'astro:assets';
import heroImage from '../images/hero.png';
const optimizedImage = await getImage({
src: heroImage,
width: 1200,
quality: 75,
formats: ['webp', 'avif', 'jpeg']
});
---
<Image
src={optimizedImage}
alt="Hero image"
loading="lazy"
/>

Starlight (the documentation theme used by this site) has built-in image handling:

  • Markdown images: Starlight automatically optimizes images in markdown files when using the @astrojs/image integration
  • Featured images: Blog posts and pages can have featured images that are optimized
  • Social images: Open Graph images are automatically generated and optimized
Terminal window
cd site
pnpm add -D @astrojs/image
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import starlightBlog from 'starlight-blog';
import { image } from '@astrojs/image';
export default defineConfig({
site: 'https://michael.wegener.engineering',
trailingSlash: 'never',
integrations: [
starlight({
// ... starlight config
}),
image(), // Add image optimization integration
],
});

With @astrojs/image configured, markdown images are automatically optimized:

![Nature Landscape](/assets/images/image-generation/1-nature-landscape.png)

Astro will:

  1. Detect the image format
  2. Generate WebP and AVIF versions
  3. Create a srcset with multiple sizes
  4. Serve the optimal format based on browser support
  • WebP: 25-35% smaller than PNG/JPEG with similar quality
  • AVIF: 50% smaller than JPEG with similar quality (modern browsers)
  • Fallback: JPEG/PNG for older browsers
  • Multiple srcset sizes for different screen resolutions
  • sizes attribute for responsive sizing
  • Automatic srcset generation based on image dimensions
  • LCP (Largest Contentful Paint): Faster image loading
  • CLS (Cumulative Layout Shift): Preserved aspect ratios prevent layout shifts
  • FID (First Input Delay): Reduced main thread blocking

The site has images in:

  • site/assets/images/image-generation/ - Blog post images (PNG format)
  • site/assets/images/team/ - Team member photos (AVIF, JPEG, WEBP formats)
  • site/assets/images/home/ - Home page images (AVIF, JPEG, WEBP formats)

Note: The team and home images already use modern formats (AVIF, WEBP) with fallbacks to JPEG/PNG, which is the recommended approach for static image assets.

  1. For markdown images: Use the @astrojs/image integration to enable automatic optimization
  2. For static assets: Continue using modern formats (AVIF, WebP) with JPEG/PNG fallbacks
  3. For blog featured images: Use the Image component or ensure markdown images are optimized
  4. For social/OG images: Ensure images are under 1200x630px and use WebP format