performanceastrolighthousetutorial

Achieving 95+ Lighthouse Score on an Astro Blog

Image optimization, font subsetting, prefetching, and bundle analysis — our full performance checklist.

3 min read 554 words Codotx Team

The 95+ Lighthouse Target

A Lighthouse score of 95+ across all four categories (Performance, Accessibility, Best Practices, SEO) is achievable with Astro — but it requires deliberate choices at every layer of the stack.

Here is the full Tsubaki checklist.

Performance

Image Optimization

Use Astro’s built-in <Image /> component for every image. It automatically:

  • Generates WebP and AVIF variants.
  • Adds correct width and height to prevent layout shift.
  • Applies loading="lazy" by default (use loading="eager" for above-the-fold images only).
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---

<Image
  src={heroImage}
  alt="Hero image"
  width={1200}
  height={630}
  loading="eager"
  fetchpriority="high"
/>

Font Loading

Render-blocking fonts are the single most common cause of poor Lighthouse scores. The correct pattern:

<!-- 1. Preconnect to font CDN. -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

<!-- 2. Preload the font CSS resource. -->
<link rel="preload" as="style"
  href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700;900&display=swap" />

<!-- 3. Load non-blocking using media swap trick. -->
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700;900&display=swap"
  media="print"
  onload="this.media='all'"
/>

<!-- 4. Fallback for no-JS environments. -->
<noscript>
  <link rel="stylesheet"
    href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700;900&display=swap" />
</noscript>

The display=swap parameter in the URL enables font-display: swap, preventing invisible text during font load.

JavaScript Bundle Strategy

  • No framework JavaScript by default — Astro ships zero runtime.
  • GSAP is loaded via dynamic import() — not in the initial bundle.
  • Use prefetch: { prefetchAll: true, defaultStrategy: 'hover' } in astro.config.mjs to preload pages on hover, before click.

Core Web Vitals

MetricTargetTsubaki Strategy
LCP< 2.5sPreload hero image, fetchpriority="high"
FID/INP< 100msNo long tasks, GSAP RAF-based
CLS< 0.1Explicit width/height on all images
TTFB< 200msStatic HTML from edge CDN

Accessibility

Semantic HTML

  • Use proper heading hierarchy (h1 → h2 → h3, never skip).
  • All interactive elements have accessible labels (aria-label or visible text).
  • Images have descriptive alt text.
  • Links describe their destination, not just “click here”.

Keyboard Navigation

  • All navigation is reachable by Tab key.
  • Mobile menu has aria-expanded and aria-controls attributes.
  • Focus styles are visible (never outline: none without a replacement).

Color Contrast

CombinationRatioWCAG Level
#1a1a1a on #faf8f517.2:1AAA
#6b6560 on #faf8f55.1:1AA
#ffffff on #c8102e5.4:1AA

Best Practices

  • All assets served over HTTPS.
  • No console errors or deprecated APIs.
  • CSP headers recommended (configure at hosting layer).
  • rel="noopener noreferrer" on all external links.

SEO

  • Unique <title> and <meta name="description"> on every page.
  • Canonical URLs to prevent duplicate content.
  • Open Graph and Twitter Card meta tags for social sharing.
  • Sitemap generated by @astrojs/sitemap.
  • RSS feed for feed readers and SEO signals.
  • JSON-LD structured data on blog posts (BlogPosting schema).

Hosting Recommendations

For the best Lighthouse scores, deploy to an edge CDN with HTTP/2 support:

  1. Vercel — Zero-config Astro support, global edge network.
  2. Netlify — Built-in CDN, easy custom headers for security.
  3. Cloudflare Pages — Fastest TTFB, 200+ edge locations.

All three support Astro’s static output with no additional configuration.