なぜAstro.jsを選んだのか - Tech Blog構築の技術選定
はじめに
おもしろテクノロジーのTech Blogを立ち上げるにあたり、技術スタックの選定は最も重要な判断の一つでした。この記事では、なぜ私たちがAstro.jsを選んだのか、その背景と判断基準を共有します。
前提: Tech Blogに求めたもの
まず、私たちがTech Blogに求めた要件を整理します。
1. パフォーマンス
- ページ読み込み速度の高速化
- SEO最適化
- Core Web Vitalsの高スコア
2. コンテンツ管理の柔軟性
- マークダウンでの執筆
- ヘッドレスCMSとの連携
- バージョン管理
3. 開発体験
4. 拡張性
- インタラクティブなUI要素の追加
- 将来的な機能拡張に対応
5. 運用コスト
- ホスティングコストの最小化
- メンテナンス負荷の軽減
技術選定の候補
検討した主な候補は以下の通りです。
| Framework | メリット | デメリット |
|---|---|---|
| Next.js | Reactエコシステム、豊富な実績、Vercel最適化 | JavaScriptバンドルサイズ大、オーバースペック |
| Gatsby | 静的サイト生成、プラグイン豊富 | ビルド時間長い、React依存 |
| Astro.js | ゼロJSデフォルト、柔軟なフレームワーク選択、高速 | 比較的新しい、日本語情報少ない |
| Hugo | 超高速ビルド、シンプル | Go言語、拡張性に限界 |
| Nuxt.js | Vueエコシステム、SSG/SSR両対応 | Vue学習コスト、バンドルサイズ |
なぜAstro.jsなのか
1. ゼロJavaScriptのデフォルト哲学
Astro.jsの最大の特徴は「デフォルトでJavaScriptを送信しない」という哲学です。
---
// サーバーサイドで実行されるコード
const posts = await getPosts();
---
<div>
{posts.map(post => (
<article>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
上記のコードは完全に静的HTMLとしてレンダリングされ、クライアントにJavaScriptは送られません。
Tech Blogのようなコンテンツ中心のサイトにおいて、これは劇的なパフォーマンス向上をもたらします。
パフォーマンスベンチマーク(想定値)
| Metric | Astro.js | Next.js SSG | Gatsby |
|---|---|---|---|
| First Contentful Paint | 0.8s | 1.2s | 1.5s |
| Time to Interactive | 1.0s | 2.5s | 3.0s |
| Total Bundle Size | 10KB | 150KB | 200KB |
2. Islands Architecture
Astro.jsの「Islands Architecture」は、必要な部分だけをインタラクティブにできます。
---
import SearchBox from '../components/SearchBox.tsx';
import GraphVisualization from '../components/GraphVisualization.tsx';
---
<!-- 静的コンテンツ -->
<header>
<h1>おもしろテクノロジー Tech Blog</h1>
</header>
<!-- インタラクティブな島 -->
<SearchBox client:load />
<!-- 記事リスト(静的) -->
<article>...</article>
<!-- インタラクティブな島(ビューポート内で遅延読み込み) -->
<GraphVisualization client:visible />
Islands Architectureのメリット
- 選択的ハイドレーション: 必要なコンポーネントだけをハイドレート
- フレームワーク混在: React、Vue、Svelte等を同一ページで使用可能
- パフォーマンス最適化: ユーザーが見ている部分だけを優先的に読み込み
3. フレームワーク非依存
Astro.jsは特定のUIフレームワークに縛られません。
---
import ReactComponent from './ReactComponent.tsx';
import VueComponent from './VueComponent.vue';
import SvelteComponent from './SvelteComponent.svelte';
---
<!-- すべて同じページで使える -->
<ReactComponent client:load />
<VueComponent client:visible />
<SvelteComponent client:idle />
私たちはReactの豊富なエコシステムを活用しつつ、将来的に他のフレームワークも選択できる柔軟性を確保しました。
4. 開発体験の良さ
TypeScript完全サポート
// src/types/post.ts
export interface Post {
title: string;
slug: string;
category: 'tech' | 'interview' | 'philosophy';
publishedAt: Date;
tags: string[];
}
// src/pages/articles/[slug].astro
---
import type { Post } from '../../types/post';
export async function getStaticPaths() {
const posts = await getPosts();
return posts.map((post: Post) => ({
params: { slug: post.slug },
props: { post }
}));
}
const { post } = Astro.props;
---
型安全性を保ちながら、快適に開発できます。
Hot Module Replacement (HMR)
Viteベースのため、高速なHMRで開発体験が快適です。
5. microCMSとの相性
ヘッドレスCMSとの連携が非常にシンプルです。
// src/lib/microcms.ts
import { createClient } from 'microcms-js-sdk';
const client = createClient({
serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
apiKey: import.meta.env.MICROCMS_API_KEY,
});
export async function getPosts() {
const { contents } = await client.get({
endpoint: 'articles',
});
return contents;
}
---
import { getPosts } from '../lib/microcms';
const posts = await getPosts();
---
<div>
{posts.map(post => (
<article>
<h2>{post.title}</h2>
<div set:html={post.body} />
</article>
))}
</div>
ビルド時に全記事を取得し、完全な静的サイトを生成します。
比較: なぜNext.jsではないのか
Next.jsは素晴らしいフレームワークですが、Tech Blogには過剰でした。
Next.jsが優れている場面
- 動的なルーティングが多い
- サーバーサイドレンダリング(SSR)が必要
- Vercelのエッジ機能を活用したい
Astro.jsが優れている場面(私たちのケース)
- コンテンツが静的
- ビルド時に全データが確定
- JavaScriptを最小限に抑えたい
パフォーマンス比較
同じブログサイトをNext.js(SSG)とAstro.jsで構築した場合の想定値:
| 指標 | Next.js | Astro.js | 差分 |
|---|---|---|---|
| 初期JavaScriptサイズ | 120KB | 5KB | -96% |
| Time to Interactive | 2.3s | 0.9s | -61% |
| Lighthouse Score | 92 | 100 | +8 |
技術スタック全体像
最終的に採用した技術スタックは以下の通りです。
┌─────────────────────────────────────┐
│ Presentation Layer │
│ Astro.js + React │
│ (Islands Architecture) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Content Layer │
│ microCMS (Headless CMS) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Styling & Animation │
│ Tailwind CSS + Framer Motion │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Deployment │
│ Cloudflare Pages / Vercel │
└─────────────────────────────────────┘
各レイヤーの役割
-
Presentation Layer (Astro.js + React)
- 静的サイト生成
- インタラクティブ要素はReact Islands
-
Content Layer (microCMS)
- 記事管理
- APIベースのコンテンツ配信
- 無料枠で十分な範囲
-
Styling & Animation
- Tailwind CSS: ユーティリティファーストでデザインシステム構築
- Framer Motion: スムーズなアニメーション
-
Deployment
- Cloudflare Pages: 高速CDN、無料枠が広い
- または Vercel: Astro最適化
実装上の工夫
1. サムネイル自動生成
OG画像を動的生成し、シェア時の見栄えを向上させます。
// src/pages/og/[slug].png.ts
import satori from 'satori';
import { html } from 'satori-html';
export async function GET({ params }) {
const post = await getPost(params.slug);
const markup = html`
<div style="background: linear-gradient(135deg, #000 0%, #1a1a2e 100%);
width: 1200px; height: 630px;
display: flex; align-items: center; justify-content: center;">
<h1 style="color: #fff; font-size: 64px;">
${post.title}
</h1>
</div>
`;
const svg = await satori(markup, { width: 1200, height: 630 });
// SVG to PNG conversion
return new Response(png, { headers: { 'Content-Type': 'image/png' } });
}
2. Pagefind統合による高速検索
---
// src/components/SearchBox.astro
---
<div id="search"></div>
<script>
import * as pagefind from 'pagefind';
pagefind.init();
pagefind.search('Astro.js').then(results => {
console.log(results);
});
</script>
ビルド時にインデックスを生成し、クライアント側で高速に検索できます。
失敗と学び
失敗1: 最初はGatsbyを検討した
当初、Gatsbyを候補に挙げていました。
問題点:
- ビルド時間が記事数に比例して長くなる
- GraphQLの学習コスト
- プラグインの依存関係管理が複雑
学び: シンプルさを優先すべきだった。Astro.jsは必要最小限の抽象化で、理解しやすい。
失敗2: 全てを静的にしようとした
最初は「完全静的サイト」を目指しましたが、検索機能やGraph UIでインタラクションが必要でした。
解決策: Islands Architectureを活用し、必要な部分だけをインタラクティブに。
学び: 完璧を目指すより、段階的に改善する方が現実的。
まとめ
Astro.jsを選んだ理由は以下の3点に集約されます。
- パフォーマンス最優先: ゼロJSデフォルトで超高速
- 柔軟性: Islands Architectureとフレームワーク非依存
- シンプルさ: 必要最小限の抽象化で理解しやすい
Tech Blogのようなコンテンツ中心のサイトにおいて、Astro.jsは最適な選択肢です。
次のステップ
- トップページワイヤーフレーム制作
- Astro + microCMS初期構築
- サムネ自動生成実装
- 初期記事10本執筆
次回の記事では、Astro.js + microCMSの実装詳細を共有します。
参考リンク
著者について
株式会社おもしろテクノロジー 岩手を拠点に、AI×製造×地方創生に取り組むテクノロジー企業
技術で社会をおもしろくする。
この記事が役立ったら、シェアしていただけると嬉しいです。