Images & Assets
Images are the low-hanging performance fruit
Section titled “Images are the low-hanging performance fruit”On most pages, images are the largest bytes on the wire — an unoptimized hero photo can outweigh all your HTML, CSS, and JavaScript combined. Astro ships an image pipeline in the built-in astro:assets module so you get modern formats, correct dimensions, and lazy loading without manual work.
The <Image /> component
Section titled “The <Image /> component”Import a local image and render it with <Image />. Astro processes it at build time — converting to an efficient format (like WebP/AVIF), and requiring width/height so the browser reserves space (no layout shift):
---import { Image } from 'astro:assets';import heroImage from '../assets/hero.png'; // a local import---<Image src={heroImage} alt="A mountain at sunrise" width={800} height={400} />What <Image /> does that a plain <img> doesn’t:
- Optimizes the file — re-encodes to a smaller modern format automatically.
- Prevents layout shift — width/height are required (inferred from local imports), so the space is reserved before the image loads.
- Lazy-loads by default — adds
loading="lazy"anddecoding="async"so off-screen images don’t block the initial render.
For a local import, Astro even knows the intrinsic dimensions, so you can omit width/height and it fills them in.
<Picture /> for multiple formats and art direction
Section titled “<Picture /> for multiple formats and art direction”When you want the browser to choose among formats, or serve a different crop at different breakpoints, use <Picture />. It renders a <picture> element with multiple <source> entries:
---import { Picture } from 'astro:assets';import hero from '../assets/hero.png';---<Picture src={hero} formats={['avif', 'webp']} alt="Sunrise" width={800} height={400} />The browser picks the first format it supports (AVIF, then WebP), falling back to the original — best compression each visitor’s browser can handle.
Local vs remote images
Section titled “Local vs remote images”- Local images (imported from
src/) are fully optimized and their dimensions are known — always prefer these. public/images are served as-is, unoptimized (Astro never touchespublic/). Use it only for things that must keep an exact path/name.- Remote images (a URL) can be optimized too, but you must list their domains as authorized in
astro.config.mjs(image.domainsorimage.remotePatterns) — a safety measure so you don’t proxy arbitrary hosts.
flowchart TB local["Imported from src/"] --> opt["Optimized, dimensions known"] remote["Remote URL"] --> auth["Optimized only if domain is authorized"] pub["In public/"] --> asis["Served as-is, not optimized"]
Optimized fonts
Section titled “Optimized fonts”Fonts are the other big, render-blocking asset. Astro’s Fonts API exposes a <Font /> component (from astro:assets) that downloads, self-hosts, and optimizes web fonts at build time — generating the right @font-face rules and preloads — so you avoid a third-party font request and the layout shift that comes with it. You configure your font families in astro.config.mjs and drop <Font /> in your head.