Astro ships zero JavaScript by default, making it one of the fastest frameworks available. Here's how to keep your Astro site scoring in the 90s and what can still go wrong.
Astro is built for performance. It ships zero JavaScript to the browser by default, uses static generation out of the box, and produces minimal, clean HTML. Most Astro sites score 90-100 on PageSpeed without any optimization.
But there are still things that can drag your score down. Here's what to watch for and how to fix it.
Astro's architecture is fundamentally different from React or Vue SPAs:
This means TBT is near zero, FCP is fast, and CLS from hydration doesn't exist. Your score problems, if any, will come from images, fonts, or the interactive islands you add.
The most common issue. Astro's built-in <Image> component from @astrojs/image handles optimization, but only if you use it.
Fix: Use Astro's Image component instead of raw <img> tags:
---
import { Image } from "astro:assets";
import heroImage from "../assets/hero.jpg";
---
<Image src={heroImage} alt="Hero" width={1200} height={630} />
This automatically converts to WebP, generates srcset, and sets correct dimensions to prevent CLS.
For external images, compress and resize them before referencing them. Aim for under 100KB for hero images.
Astro lazy-loads images by default. Your hero image should load eagerly.
Fix: Add loading="eager" and fetchpriority="high" to your LCP image:
<Image
src={heroImage}
alt="Hero"
width={1200}
height={630}
loading="eager"
fetchpriority="high"
/>
Every time you use client:load, client:visible, or client:idle on a component, you're shipping JavaScript. If you have many interactive islands loading on the initial page view, TBT will climb.
Fix: Use the right hydration directive for each component:
client:load - loads immediately (use only when necessary)client:idle - loads when the browser is idle (good for non-critical UI)client:visible - loads when the component enters the viewport (best for below-fold)client:media - loads only on certain screen sizesReplace client:load with client:idle wherever the component doesn't need to be interactive immediately.
Analytics, chat widgets, and other third-party scripts affect Astro sites just like any other. Astro doesn't shield you from these.
Fix: Use Astro's <script> tag with is:inline only for truly critical scripts. For analytics, add the script at the bottom of your layout with defer:
<script defer src="https://analytics.example.com/script.js"></script>
Or use a lightweight analytics tool. Astro integrates well with Partytown, which runs third-party scripts in a web worker off the main thread:
npx astro add partytown
Loading fonts from Google Fonts adds an external DNS lookup and render-blocking request.
Fix: Download your fonts and self-host them in your public/fonts/ directory. Add font-display: swap and preload your primary font:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin />
Astro's View Transitions feature (<ViewTransitions />) adds a small JavaScript bundle to enable smooth page transitions. If you're chasing a perfect 100 score, this adds a few milliseconds of TBT.
For most sites the trade-off is worth it. If you're obsessing over those last few points, you can remove it.
Astro sites consistently outperform other frameworks. Realistic targets:
| Setup | Realistic Score | |---|---| | Static site, optimized images, no third-party | 95-100 | | Few interactive islands, lightweight analytics | 90-95 | | Multiple client:load islands, third-party scripts | 75-90 | | Heavy SSR with dynamic content | 70-85 |
Astro's static output shines when deployed to edge networks. The fastest options:
Avoid deploying static Astro sites to traditional shared hosting. The CDN is where the speed comes from.
astro:assets Image component for all imagesloading="eager" and fetchpriority="high"client:idle or client:visible instead of client:load where possibledefer or PartytownIf you're using Astro and scoring below 85, something specific is causing it. The most likely culprits are images and third-party scripts.
Test your Astro site to get your exact score and a breakdown of what's affecting each metric.
How fast is your site?
Get your PageSpeed score in seconds — free, no sign-up needed.
Test Your Site →