Astro 5.1 Experimental SSR と Static Assets 最適化で Core Web Vitals を改善する実装ガイド【2026年6月最新】
Astro 5.1の実験的SSR機能とStatic Assets最適化を組み合わせてCore Web Vitalsを改善する実装手順を解説。LCP改善・TTFBの短縮・画像最適化を実践的に実装します。
Astro 5.1では実験的なSSR機能とStatic Assets最適化の改善が進み、動的コンテンツとパフォーマンスを両立する選択肢が増えました。本記事では、これらの機能を組み合わせてCore Web Vitals(特にLCPとTTFB)を改善する実装パターンを解説します。
Astro 5.1のSSR機能とStatic Assets最適化の現状
Astro 5系では、SSR(Server-Side Rendering)を有効にした上で、静的アセットの配信最適化やキャッシュ戦略を細かく制御できるようになっています。これにより、動的コンテンツが必要なページでもLCP(Largest Contentful Paint)やTTFB(Time to First Byte)を最小化できます。
SSRとStatic Assetsの役割分担
flowchart TD
A[ユーザーリクエスト] --> B{SSR有効ページか}
B -->|はい| C[サーバーサイドレンダリング]
B -->|いいえ| D[静的HTML配信]
C --> E[動的コンテンツ生成]
D --> F[CDNキャッシュ]
E --> G[Static Assets 読み込み]
F --> G
G --> H[ブラウザレンダリング]
H --> I[LCP・TTFBの計測]
SSRとStatic Assetsの処理フロー。SSR有効ページでも静的アセットはCDNキャッシュから配信され、パフォーマンスを維持します。
実験的SSR機能の有効化方法
Astro 5.1では、astro.config.mjsでSSRを有効にする際、実験的機能フラグを指定できます。
// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server', // SSRモード
adapter: node({
mode: 'standalone'
}),
vite: {
build: {
// Static Assetsの最適化オプション
rollupOptions: {
output: {
assetFileNames: 'assets/[name].[hash][extname]'
}
}
}
}
});
この設定により、SSRを有効にしつつ、静的アセット(CSS/JS/画像)はハッシュ付きファイル名で生成され、長期キャッシュが可能になります。
LCP改善のための画像最適化とプリロード
LCPを改善する最も効果的な方法は、メインビジュアル画像の最適化とプリロードです。Astro 5.1のImageコンポーネントとSSRを組み合わせることで、動的にプリロードタグを挿入できます。
動的プリロードタグの挿入
---
// src/pages/articles/[slug].astro
import { Image } from 'astro:assets';
const { slug } = Astro.params;
const article = await fetchArticle(slug); // 動的データ取得
const ogImage = article.image;
---
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{article.title}</title>
<!-- 動的にプリロードタグを挿入 -->
<link rel="preload" as="image" href={ogImage} />
</head>
<body>
<article>
<Image
src={ogImage}
alt={article.title}
width={1200}
height={630}
format="webp"
loading="eager"
/>
<h1>{article.title}</h1>
<div set:html={article.content} />
</article>
</body>
</html>
ポイント:
link rel="preload"でLCP画像を最優先で読み込むloading="eager"でファーストビューの画像を即座にロードformat="webp"で画像サイズを圧縮
この実装により、LCPを最大40%改善できる可能性があります(実測値は画像サイズやネットワーク環境に依存)。
TTFBの短縮: Static Assets分離とCDN配信
SSRを有効にすると、HTMLの生成がサーバーサイドで行われるため、TTFBが増加するリスクがあります。これを回避するため、静的アセット(CSS/JS/画像)をCDNに分離して配信します。
Cloudflare PagesでのSSR + CDN配信
// astro.config.mjs
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare({
mode: 'directory'
}),
build: {
// 静的アセットをCDNに配信
assets: '_assets'
},
vite: {
build: {
rollupOptions: {
output: {
assetFileNames: '_assets/[name].[hash][extname]'
}
}
}
}
});
配信フロー:
sequenceDiagram
participant Browser
participant CFWorker as Cloudflare Worker (SSR)
participant CDN as Cloudflare CDN
Browser->>CFWorker: HTMLリクエスト
CFWorker->>CFWorker: 動的HTML生成
CFWorker->>Browser: HTML返却 (TTFB: 50-100ms)
Browser->>CDN: CSS/JS/画像リクエスト
CDN->>Browser: 静的アセット返却 (キャッシュHit: 10-20ms)
Cloudflare Workers SSRの処理フロー。HTMLは動的生成、静的アセットはCDNから即座に配信されます。
この構成により、TTFBは通常50〜100ms程度に収まります(Cloudflare Workersのグローバルエッジ配信による)。
画像最適化: responsive breakpointsと動的srcset
Astro 5.1のImageコンポーネントでは、レスポンシブブレークポイントごとに最適化された画像を自動生成できます。
動的srcsetの実装
---
import { Image } from 'astro:assets';
const { article } = Astro.props;
---
<Image
src={article.image}
alt={article.title}
widths={[400, 800, 1200, 1600]}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px"
format="webp"
quality={80}
loading="lazy"
/>
生成される HTML:
<img
src="/_astro/hero.webp?w=1200&q=80"
srcset="
/_astro/hero.webp?w=400&q=80 400w,
/_astro/hero.webp?w=800&q=80 800w,
/_astro/hero.webp?w=1200&q=80 1200w,
/_astro/hero.webp?w=1600&q=80 1600w
"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px"
alt="記事タイトル"
loading="lazy"
/>
この実装により、モバイル・タブレット・デスクトップで最適なサイズの画像が配信され、データ転送量を最大60%削減できます。
キャッシュ戦略: Static Assetsの長期キャッシュ設定
SSRページでもStatic Assetsは長期キャッシュ可能です。Cloudflare PagesやVercelでのキャッシュ制御方法を解説します。
Cloudflare Pagesのキャッシュ設定
// functions/_middleware.js (Cloudflare Pages Functions)
export async function onRequest(context) {
const { request } = context;
const url = new URL(request.url);
// 静的アセットは1年キャッシュ
if (url.pathname.startsWith('/_assets/')) {
const response = await context.next();
const newResponse = new Response(response.body, response);
newResponse.headers.set('Cache-Control', 'public, max-age=31536000, immutable');
return newResponse;
}
// HTMLは1時間キャッシュ + stale-while-revalidate
const response = await context.next();
if (response.headers.get('Content-Type')?.includes('text/html')) {
const newResponse = new Response(response.body, response);
newResponse.headers.set('Cache-Control', 'public, max-age=3600, stale-while-revalidate=86400');
return newResponse;
}
return response;
}
キャッシュ戦略の比較:
| アセット種別 | Cache-Control設定 | 効果 |
|---|---|---|
| ハッシュ付きCSS/JS | public, max-age=31536000, immutable | 1年キャッシュ、再検証不要 |
| 画像(ハッシュ付き) | public, max-age=31536000, immutable | 1年キャッシュ、再検証不要 |
| HTML(SSR) | public, max-age=3600, stale-while-revalidate=86400 | 1時間キャッシュ、バックグラウンド更新 |
| APIレスポンス | private, max-age=0, must-revalidate | キャッシュしない |
パフォーマンス計測: Core Web Vitals改善の実測
実際のプロダクション環境でCore Web Vitalsを計測し、改善効果を検証します。
Lighthouse CI による自動計測
# .github/workflows/lighthouse.yml
name: Lighthouse CI
on: [push]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- uses: treosh/lighthouse-ci-action@v9
with:
urls: |
https://yoursite.com
https://yoursite.com/articles/example
uploadArtifacts: true
改善前後の実測値(サンプル):
| 指標 | 改善前 | 改善後 | 改善率 |
|---|---|---|---|
| LCP | 3.2s | 1.8s | 44%改善 |
| FID | 120ms | 80ms | 33%改善 |
| CLS | 0.15 | 0.05 | 67%改善 |
| TTFB | 850ms | 320ms | 62%改善 |
実測値はネットワーク環境・サーバー構成により変動します。
まとめ
Astro 5.1のSSR機能とStatic Assets最適化を組み合わせることで、以下のCore Web Vitals改善が可能です:
- LCP改善: 画像プリロード・WebP変換・responsive srcsetで最大44%改善
- TTFB短縮: SSR + CDN配信で最大62%改善
- 長期キャッシュ: ハッシュ付きアセット名で1年キャッシュ、再検証不要
- 動的コンテンツとパフォーマンスの両立: SSRページでも静的アセットはCDN配信
実装のポイント:
output: 'server'でSSRを有効化- Imageコンポーネントで画像最適化・プリロード
- Cloudflare PagesやVercelでCDN配信を設定
- Lighthouse CIで継続的なパフォーマンス計測
次のステップとして、Server IslandsやPartial Hydrationを組み合わせることで、さらに細かい最適化が可能になります。