Astro provides various performance optimization strategies and techniques to help developers build ultra-fast websites. Understanding these optimization techniques is crucial for building high-performance Astro applications.
Core Performance Optimization Strategies:
-
Zero JavaScript by Default:
- Astro outputs pure HTML by default
- Only loads JavaScript when needed
- Significantly reduces initial load time
-
Islands Architecture Optimization:
- Only add
client:*directives to interactive components - Use appropriate
client:*directive types - Defer hydration of non-critical interactions
- Only add
Code Splitting and Lazy Loading:
astro--- // Lazy load components import { lazy } from 'astro'; const HeavyComponent = lazy(() => import('../components/HeavyComponent.jsx')); --- <HeavyComponent client:visible />
Image Optimization:
astro--- import { Image } from 'astro:assets'; import heroImage from '../assets/hero.jpg'; --- <!-- Use correct formats and sizes --> <Image src={heroImage} alt="Hero" widths={[400, 800, 1200, 1600]} sizes="(max-width: 768px) 100vw, 50vw" formats={['avif', 'webp', 'jpeg']} loading="eager" priority={true} /> <!-- Lazy load non-critical images --> <Image src={image} alt="Gallery Image" loading="lazy" decoding="async" />
CSS Optimization:
astro--- // Use scoped styles --- <style> /* Scoped styles, won't affect other components */ .container { max-width: 1200px; margin: 0 auto; } </style> <style is:global> /* Global styles, use sparingly */ body { font-family: system-ui, sans-serif; } </style>
Preloading Critical Resources:
astro--- // src/layouts/Layout.astro --- <html> <head> <!-- Preload critical CSS --> <link rel="preload" href="/styles/critical.css" as="style" /> <!-- Preload fonts --> <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin /> <!-- Preconnect to external domains --> <link rel="preconnect" href="https://api.example.com" /> <!-- DNS prefetch --> <link rel="dns-prefetch" href="https://cdn.example.com" /> </head> <body> <slot /> </body> </html>
Data Fetching Optimization:
astro--- // src/pages/blog/[slug].astro import { getEntry } from 'astro:content'; // Fetch data in parallel const [post, relatedPosts, comments] = await Promise.all([ getEntry('blog', Astro.params.slug), fetchRelatedPosts(Astro.params.slug), fetchComments(Astro.params.slug), ]); // Use caching const cachedData = await cache.get(`post:${Astro.params.slug}`); if (cachedData) { return cachedData; } const data = await fetchData(); await cache.set(`post:${Astro.params.slug}`, data, { ttl: 3600 }); --- <h1>{post.data.title}</h1> <Content />
Build Optimization:
javascript// astro.config.mjs import { defineConfig } from 'astro/config'; export default defineConfig({ build: { // Optimize build output inlineStylesheets: 'auto', }, vite: { build: { // Code splitting rollupOptions: { output: { manualChunks: { vendor: ['react', 'react-dom'], utils: ['lodash', 'date-fns'], }, }, }, }, }, });
Server-Side Rendering Optimization:
typescript// src/middleware.ts export const onRequest = async (context, next) => { // Add cache headers const response = await next(); // Add long-term cache for static assets if (context.url.pathname.match(/\.(js|css|png|jpg|jpeg|gif|webp|svg)$/)) { response.headers.set('Cache-Control', 'public, max-age=31536000, immutable'); } // Add short-term cache for API responses if (context.url.pathname.startsWith('/api/')) { response.headers.set('Cache-Control', 'public, max-age=60'); } return response; };
Using Adapters for Deployment Optimization:
javascript// astro.config.mjs import { defineConfig } from 'astro/config'; import vercel from '@astrojs/vercel/server'; export default defineConfig({ output: 'server', adapter: vercel({ // Vercel-specific optimizations imageService: true, edgeMiddleware: true, }), });
Performance Monitoring and Analysis:
typescript// src/lib/performance.ts export function measurePerformance(name: string, fn: () => Promise<void>) { return async () => { const start = performance.now(); await fn(); const duration = performance.now() - start; console.log(`${name} took ${duration.toFixed(2)}ms`); }; } // Usage export async function GET(context) { await measurePerformance('data-fetch', async () => { const data = await fetchData(); return new Response(JSON.stringify(data)); }); }
Web Vitals Optimization:
astro--- // src/layouts/Layout.astro --- <html> <head> <script> // Monitor Core Web Vitals import { onCLS, onFID, onFCP, onLCP, onTTFB } from 'web-vitals'; onCLS(console.log); onFID(console.log); onFCP(console.log); onLCP(console.log); onTTFB(console.log); </script> </head> <body> <slot /> </body> </html>
Reducing Third-Party Scripts:
astro--- // Lazy load analytics scripts --- <script> // Only load in production if (import.meta.env.PROD) { window.addEventListener('load', () => { const script = document.createElement('script'); script.src = 'https://analytics.example.com/script.js'; script.async = true; document.head.appendChild(script); }); } </script>
Using Service Worker for Caching:
typescript// public/sw.js const CACHE_NAME = 'astro-v1'; const urlsToCache = ['/', '/styles/main.css']; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache)) ); }); self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => response || fetch(event.request)) ); });
astro--- // Register Service Worker --- <script> if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js'); }); } </script>
Performance Optimization Checklist:
-
Build-time Optimization:
- Enable code splitting
- Compress and optimize assets
- Use Tree Shaking
- Optimize images and fonts
-
Runtime Optimization:
- Use appropriate
client:*directives - Implement lazy loading
- Optimize data fetching
- Use caching strategies
- Use appropriate
-
Network Optimization:
- Use CDN
- Enable compression (gzip, brotli)
- Optimize HTTP requests
- Use HTTP/2 or HTTP/3
-
Rendering Optimization:
- Reduce repaints and reflows
- Use CSS animations instead of JavaScript
- Optimize DOM structure
- Avoid forced synchronous layouts
Performance Testing Tools:
- Lighthouse
- WebPageTest
- Chrome DevTools Performance
- Astro's built-in build analysis
Astro's performance optimization strategies help you build ultra-fast websites with excellent user experience and SEO performance.