Day14 - Astro Series: Image Optimization

A pretty gradient background with a heading: "Image Optimization"

Introduction

Images often accompany content, and they can consume the majority of a page’s compute resources and bandwidth. You want images to be handled well so they don’t degrade the overall site experience. Astro includes built-in components and methods to help you manage these concerns.

Where to store images src/ vs public/

There are two places to put project images: the src or public folders. The difference is that Astro only transforms or optimizes images that come from src, so if you want images to be processed it’s recommended to place them in the src folder. Otherwise you can store them in public/.

Transforming and optimizing images

Providing appropriate image sizes, loading strategies, formats, or quality can effectively improve page load performance. Astro’s built-in <Image /> component is designed to help achieve this. First, import the component from astro:assets and apply it in your template.

---
import { Image } from 'astro:assets'
import myImage from '../assets/image.png'
---
<Image src={myImage} alt="" />

Using the <Image /> component will produce the following result; you can see the image is automatically given several attributes by default:

<img src="/_astro/image.hash.webp" width="1600" height="900" decoding="async" loading="lazy" alt="" />

The default values for these attributes cannot be changed directly, but you can create your own component to encapsulate and set defaults🔗. Specifically, the attributes include:

  • src (required): The source. This attribute will vary depending on where the image is stored.
    • Local images in the src/ folder: you need to import the image and pass the imported name to the src attribute.
    ---
    import { Image } from 'astro:assets';
    import myImportedImage from `../assets/my-local-image.png`
    ---
    <Image src={myImportedImage} alt="descriptive text" />
    • Local images in the public/ folder
    ---
    import { Image } from 'astro:assets';
    ---
    <Image
    src="/images/my-public-image.png"
    alt="descriptive text"
    width="200"
    height="150"
    />
    • Remote images
    ---
    import { Image } from 'astro:assets';
    ---
    <Image
    src="https://example.com/remote-image.jpg"
    alt="descriptive text"
    width="200"
    height="150" />
  • alt (required): Alternative text. Providing descriptive image alternative text🔗 is mandatory; if the image is purely decorative you can pass an empty string so screen readers or other assistive technologies know the image can be ignored.
  • width and height: Width and height. When the image source comes from public/ or a remote image, Astro cannot analyze those images’ details, so you must supply these to avoid layout shift🔗 issues.
  • format: Image format; by default Astro will generate and use .webp images.
  • quality
    • Levels: low, mid, high, max (standardized across formats)
    • A number from 0 to 100 (interpreted differently across formats)
  • Additional attributes (any attribute accepted by <img>)

Conclusion

By handling images properly—writing alt text, specifying dimensions, lazy-loading, providing appropriate sizes and formats, and adjusting quality—optimizing images is one of the highest ROI ways to improve web performance.

Further reading