Adding image optimization to Astro using @astrojs/image

It seems that Astro doesn't support image optimization (output formats, resizing etc) in markdown content.
It does however support using image components within pages & mdx content.

Why @astrojs/image?

Images play a big role in overall site performance and usability. Serving properly sized images makes all the difference but is often tricky to automate.

This integration provides <Image /> and <Picture> components as well as a basic image transformer, with full support for static sites and server-side rendering. The built-in image transformer is also replaceable, opening the door for future integrations that work with your favorite hosted image service.


@astrojs/image 🚀 Astro Documentation

Features #

Installing astrojs/image #

Looking at the documentation it's recommended you use sharp with @astrojs/image.

pnpm add -D @astrojs/image sharp

Add the plugin to astro.config.mjs with options to use sharp

import image from '@astrojs/image'
    image({
      serviceEntryPoint: '@astrojs/image/sharp',
    }),

Optimizing Hero Images #

The main image in blog posts on this site is the hero image.

The heroImage component can be found in each layout (posts & pages).

        {
          heroImage && (
            <div class="hero-image">
              <img src={heroImage} alt="" />
            </div>
          )
        }

I decided to use the <Picture /> component from @astrojs/image as this allows an array of sizes to use for responsive images.

import { Picture } from '@astrojs/image/components'
        {
          heroImage && (
            <div class="hero-image">
              <Picture
                src={heroImage}
                widths={[400, 800, 1200]}
                sizes="(max-width: 1200px) 100vw, 1200px"
                alt=""
                aspectRatio={1200 / 500}
              />
            </div>
          )
        }

This configuration creates 3 image sizes (400px, 800px, 1200px) with 2 formats (avif, webp).
It also has aspect ratio set so images are resized & cropped.

Browser Based Lazy Loading #

The component also adds loading="lazy" decoding="async" to img utilizing browser based lazy loading.

The loading attribute on an <img> element (or the loading attribute on an <iframe>) can be used to instruct the browser to defer loading of images/iframes that are off-screen until the user scrolls near them.


Lazy loading - Web performance | MDN

Source #

The source for this site is available on github.

blog-astro