Astro Starts Fast. Keep It Fast.
Performance
Astro's defaults are fast. A handful of habits keep it that way — audit hydration, watch image sizes, prefer scripts over islands.
What you'll learn
- Audit JS shipped per page
- Pick the lightest hydration directive
- Spot the common regressions
Astro starts fast: HTML by default, no framework runtime, optimized images. To keep it that way, a handful of habits.
Audit JS Per Page
Open DevTools → Network → filter by JS. On a content page, you should see a tiny amount — Astro’s hydration shim plus any framework runtimes for islands.
If a content page is shipping 100+ KB of JS, something’s wrong:
- A component you thought was static is actually a hydrated island
- A non-island component imports a heavy library that gets bundled
Pick The Lightest Directive
For an interactive widget below the fold, client:visible is
almost always the right choice. Reserve client:load for things
that need to be interactive immediately.
| Cost (lowest → highest) | Directive |
|---|---|
| No JS | (no client:*) |
client:visible | Only if scrolled to |
client:idle | When browser is idle |
client:load | Immediately at load |
client:only="..." | No SSR, always JS |
Image Discipline
- Use
<Image>for everything insrc/ - Set widths to match actual display size (don’t ship a 4000px image for a 400px slot)
- Use
<Picture>for art direction across breakpoints - Lazy-load below-the-fold images (default with
<Image>)
Avoid Big Serialized Props
If you <Component data={hugeArray} client:load />, that hugeArray
gets inlined into the HTML and parsed on the client. Either fetch it
inside the island or move the rendering into the surrounding Astro
template.
Tools
- Lighthouse in Chrome DevTools — easy first audit
@astrojs/web-vitalsintegration — collect real-user metricsnpm run build -- --verbose— see per-page asset sizes
A Quick Checklist
- Hero image uses
<Image>(not raw<img>) - No islands shipping unused frameworks
<script>for behavior that doesn’t need a framework- Caching headers set for server-mode pages
- Layout doesn’t accidentally include a heavy import
- Fonts subset to characters you actually use
Up Next
Deploying static sites.
Static Deployment →