言語を切り替える
テーマを切り替える

Astro 5でブログを再構築し、Lighthouseスコアを68から100にした話

先週、私はある決断をしました。2年間使ってきたNext.js製のブログを全面的にリニューアルし、Astro 5に移行したのです。
きっかけは衝動的なものでした。Lighthouseのスコアを何気なく測ってみたら、目に飛び込んできたのは「68点」という衝撃的な数字。私のブログ、そんなに遅かったのか……。ある日友人に記事のリンクを送ったら、「読み込み中のグルグルが長すぎて閉じちゃった」と言われ、その場で穴に入りたくなりました。

移行完了後、ビルド時間は2分から18秒に激減し、パフォーマンススコアは68から98へ跳ね上がりました。ここまでの劇的な変化は、正直予想以上でした。
この記事では、なぜAstroがこんなに速いのか、どうやってブログを構築するのか、そしてSEOの設定方法についてお話しします。ブログの表示速度に悩んでいる方、必見です。

68→98
Lighthouseスコア
Next.jsからAstro 5への移行
2分→18秒
ビルド時間
ビルド時間を85%短縮
2.1秒→0.8秒
FCP(初期表示)
62%高速化
4.5秒→1.2秒
TTI(操作可能)
73%高速化
280KB→45KB
JSサイズ
84%削減
60%
Core Web Vitals合格率
Astroサイト平均。WP/Gatsbyは38%
数据来源: 実プロジェクト測定データ

なぜ今、Astroなのか?

正直なところ、最初Astroにはあまり興味がありませんでした。Next.js、Nuxt、Gatsby……フレームワークはもう十分すぎるほどあります。「また新しいものを覚えるの? その投資に見合う価値はあるの?」と懐疑的でした。
しかし、あるデータを見て考えが変わりました。
State of JavaScript 2024の調査で、Astroは「関心度」「継続利用意向」「満足度」で1位を獲得。利用率でもNext.jsに次ぐ2位でした。GitHub Octoverse 2025でも、成長率第3位の言語(フレームワーク)として挙げられています。
さらに興味深いデータがあります。Astro製サイトの60%がCore Web Vitalsの評価に合格しているのに対し、WordPressやGatsbyは38%にとどまっています。この差は無視できません。

採用企業も増えています。GitHubのドキュメント、Firebaseの開発者ドキュメント、Smashing Magazine(WordPressから移行)など、名だたる企業が使っています。GoogleやReuters、Typstも2025年には導入を始めています。

ここで冷静に考えてみました。私のブログに必要な機能は何だろう? 基本はMarkdownの記事表示、コードハイライト、たまにコメント機能があるくらい。Next.jsのような複雑なフルスタック機能は必要ないのでは?

私の結論はこうです:「ブログ、ドキュメントサイト、LP(ランディングページ)を作るなら、Astroは現時点での最適解。逆に、ECサイトやSaaSのような複雑なインタラクションが必要なアプリなら、Next.jsの方が適している」
どちらが優れているかではなく、適材適所の問題です。

Islandアーキテクチャ——Astroの爆速の秘密

「ページの内容は表示されているのに、ボタンを押しても反応しない」という経験はありませんか?
これはJavaScriptのハイドレーション(Hydration)が原因であることが多いです。従来のフレームワークは、ページ全体のJSをブラウザに送りつけ、ブラウザ側でそれを「再構築(アクティベート)」させます。ページが複雑になるほど、この待ち時間は長くなります。

Astroのアプローチは根本的に異なります。「アイランド(Island)アーキテクチャ」と呼ばれる仕組みを採用しています。
これはどういうことかと言うと、ページ全体を「静的なHTMLの海」と見なし、その中に「インタラクティブな島(Island)」を浮かべるイメージです。カウンター、フォーム、コメント欄といった実際に動く必要があるコンポーネントだけが独立した「島」となり、それぞれが独自にJavaScriptを管理します。島同士は干渉しません。

コードで見るとこんな感じです:

---
// このコンポーネントは、ユーザーがスクロールして画面内に現れた時だけJSを読み込む
---
<Counter client:visible />

// このコンポーネントは永遠に純粋な静的HTML。JSは一切読み込まない
<Header />

client:visible というディレクティブが見えますか? これが「ユーザーに見えた時だけアクティブにする」というAstroへの指示です。他にも client:load(ページ読み込み時)、client:idle(ブラウザのアイドル時)などが選べます。

実際の効果は? 私のブログでは、FCP(First Contentful Paint)が2.1秒から0.8秒に、TTI(Time to Interactive)が4.5秒から1.2秒に短縮されました。JSバンドルサイズに至っては、280KBから45KBまでダイエットに成功しました。

ただし、公平を期して言うなら、ページ全体がインタラクティブな要素で構成されている場合、Astroのメリットは薄れます。Astroの強みは「コンテンツの大部分が静的である」というシナリオで発揮されます。ブログやドキュメントサイトにとっては、まさに最強のツールと言えるでしょう。

Server Islands——Astro 5の新兵器

Astro 5では「Server Islands」という新機能が追加されました。これがまた面白いんです。
これまで、「ページの大部分は静的だけど、一部だけ動的コンテンツ(ユーザーアバターやカートの点数など)がある」場合、ページ全体を動的レンダリング(SSR)にするか、パーソナライズを諦めるしかありませんでした。

Server Islandsの解決策はこうです:「まず静的なHTMLの外側をユーザーに返し、動的な部分は後からサーバーが注入する」
公式には「パフォーマンスとパーソナライズはもはや対立しない」と謳っています。実際に使ってみましたが、非常にスムーズで違和感がありません。

Content Layer——新しいコンテンツ管理手法

ブログ記事が100を超えると、コンテンツ管理がカオスになってきます。
従来は src/content ディレクトリにMarkdownファイルを詰め込み、ファイルシステム頼りで整理していました。記事が少なければいいのですが、増えるとファイルを探すのも一苦労、CMSを導入するのも面倒でした。

Astro 5の Content Layer はこの問題を根底から解決します。
核となるのは「Loader」という仕組みです。ローカルのMarkdownはもちろん、Strapi、Contentful、Notion、さらには自作APIまで、あらゆる場所からコンテンツをロードできます。データソースが統一されるので、管理が劇的に楽になります。

// astro.config.mjs
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
  loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
  schema: z.object({
    title: z.string(),
    pubDate: z.date(),
    tags: z.array(z.string()),
  }),
});

この設定は、「./src/content/blog ディレクトリからすべてのMarkdownファイルを読み込み、各記事には必ず titlepubDatetags のフィールドを持たせる」という意味です。

パフォーマンス面でも、公式発表ではMarkdownのビルド速度が最大5倍、MDXが2倍向上し、メモリ使用量が25〜50%削減されるとのこと。私のブログのビルド時間が2分から18秒になったのも、この恩恵が大きいでしょう。
現在は glob loaderでローカルMarkdownを読み込んでいますが、将来的にはNotionと連携させて、執筆と公開を分離しようと画策しています。

View Transitions——アプリのような滑らかな遷移

ここは簡単におさらいします。
Astro 5では、従来の ViewTransitions コンポーネントが ClientRouter にリネームされました。機能は同じですが、役割がより明確になりました——そう、クライアントサイドルーティングです。

---
import { ClientRouter } from 'astro:transitions';
---
<html>
  <head>
    <ClientRouter />
  </head>
  <body>
    <!-- コンテンツ -->
  </body>
</html>

これを追加するだけで、ページ遷移時にフェードなどのアニメーションが付き、SPA(シングルページアプリケーション)のような滑らかな体験になります。
2025年現在、ネイティブのView Transitions APIはほぼすべてのモダンブラウザでサポートされています(Firefoxが最後でした)。ClientRouterは非対応ブラウザへのフォールバックも自動で提供してくれます。
音楽プレーヤーのようにページを跨いで状態を維持したい機能があるなら、ClientRouterは必須です。単にクロスフェードさせたいだけなら、ネイティブのCSS View Transitionsだけでも十分かもしれません。

SEO最適化の実践設定

ここが重要です。「Astroは速いからSEOもバッチリ」と思っている方が多いですが、速度は評価の一部に過ぎません。ページ構造の明確さやメタデータの正確さも、検索エンジンは見ています。
私が最初の設定でハマったポイントを含め、正しい設定方法を共有します。

Sitemap設定

基本中の基本ですが、忘れがちなのがサイトマップ。

npx astro add sitemap

そして astro.config.mjs にサイトURLを記述します:

import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
  site: 'https://yourdomain.com', // これを忘れないで!
  integrations: [sitemap()],
});

私は最初 site の設定を忘れ、生成されたサイトマップがすべて相対パスになってしまい、Google Search Consoleに怒られました。気付くまで数日かかりました……。

Metaタグ管理

各記事に固有のタイトルと説明文(Description)を設定しましょう。私はMarkdownのfrontmatterで統一管理しています:

---
title: "Astro 5 パフォーマンス最適化ガイド"
description: "Astro 5のIslandアーキテクチャとContent Layerを徹底解説..."
publishDate: 2025-11-20
ogImage: "/images/astro-5-cover.png"
---

そして、レイアウトコンポーネントでこれらを読み込みます:

---
const { title, description, ogImage } = Astro.props.frontmatter;
---
<head>
  <title>{title}</title>
  <meta name="description" content={description} />
  <meta property="og:title" content={title} />
  <meta property="og:description" content={description} />
  <meta property="og:image" content={ogImage} />
  <link rel="canonical" href={Astro.url} />
</head>

canonical URLの設定は重要です。同一コンテンツが別URLで存在する場合の重複評価を防ぎます。

構造化データ(JSON-LD)

意外と知られていませんが、SEO効果の高い設定です。検索エンジンに「これはブログ記事です」「著者は誰です」「公開日はいつです」と明確に伝えることができます。

<script type="application/ld+json">
  {JSON.stringify({
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "headline": title,
    "datePublished": publishDate,
    "author": {
      "@type": "Person",
      "name": "あなたの名前"
    }
  })}
</script>

Schema.org Validator で正しく設定できているかチェックできます。

2025年のSEOトレンド

今年特に重要視されているポイントをいくつか:

  1. LLMもクロールしている: 検索エンジンだけでなくAIもあなたのサイトを見ています。キーワードの羅列より、構造化された情報の質が重要です。
  2. 内部リンク: 各ページに最低3つの内部リンクが必要です。孤立したページは検索エンジンに「価値が低い」と判断されやすくなります。
  3. E-E-A-T: 経験(Experience)、専門性(Expertise)、権威性(Authoritativeness)、信頼性(Trustworthiness)。Googleのランキング要因として、これらはもはや精神論ではなく実数として評価されます。

SEOチェックリスト

設定完了後、このリストで確認してください:

  • sitemap.xml が生成され、アクセス可能か
  • 全ページに固有の title と description があるか
  • 全画像に alt 属性があるか
  • JSON-LD 構造化データを追加したか
  • robots.txt は正しく設定されているか
  • 各ページに3つ以上の内部リンクがあるか

画像最適化——見落としがちなパフォーマンスキラー

「画像を圧縮すればいいんでしょ?」と思っていませんか? 画像最適化はもっと奥が深いです。
Astroには強力な astro:assets モジュールと Image コンポーネントが組み込まれています。

---
import { Image } from 'astro:assets';
import myImage from '../assets/hero.png';
---
<Image
  src={myImage}
  alt="Hero image"
  widths={[400, 800, 1200]}
  format="webp"
/>

このコードがやってくれること:

  1. 画像の縦横比を自動推論し、レイアウトシフト(CLS)を防ぐ。
  2. 複数のサイズの画像を生成し、ブラウザが最適なサイズを自動で選んでロードする。
  3. 軽量なWebP形式に自動変換する。

超重要ポイント:画像は public ではなく src ディレクトリに置いてください。
src 内の画像はAstroによって最適化処理されますが、public 内の画像はそのまま配信されます。私は最初これを知らずに public に画像を置いていて、ファイルサイズが巨大なままでした。

リモート画像のサイズ自動取得も便利です:

<Image
  src="https://example.com/image.jpg"
  alt="Remote image"
  inferSize
/>

効果は劇的です。AstroEdgeというOSSプロジェクトのテストでは、画像総容量が4.2MBから0.8MBへ82%削減され、パフォーマンススコアが79から100へ改善したというデータがあります。
Astro 5では実験的な画像クロップ機能やSVGコンポーネントのサポートも追加されました。

他のフレームワークからの移行について

Astro 4や他フレームワークからの移行を考えている方向けのメモです。
Astro 5の主な変更点:

  1. ViewTransitionsClientRouter に名称変更。
  2. Astro.glob() が非推奨に。import.meta.glob() または getCollection() を推奨。
  3. Hybridレンダリングモードがstatic出力に統合。
  4. 画像処理エンジンがSquooshからSharpに変更(高速化)。
  5. CSRF保護がデフォルトで有効化。

アップグレードは簡単です:

npx @astrojs/upgrade

このコマンドが主要な互換性処理を行ってくれます。手動修正が必要な箇所もガイドしてくれます。
Next.jsやGatsbyからの移行は少し骨が折れますが、AstroはReactコンポーネントをそのまま使えるので、「とりあえずページをAstroに移し、コンポーネントはReactのまま使う(徐々にAstro化する)」という戦略が取れます。

まとめ

長くなりましたが、要点は以下の通りです:

  1. Islandアーキテクチャにより、デフォルトでJSゼロのページが生成され、パフォーマンスが劇的に向上する。
  2. Content Layerですべてのコンテンツソースを統一管理できる。
  3. SEO設定は数ステップだが、効果は絶大。sitemapとcanonicalを忘れずに。
  4. 画像最適化src ディレクトリに置くだけで恩恵を受けられる。
  5. View Transitions(ClientRouter)でアプリのような操作感を実現できる。

もしフレームワーク選びで迷っているなら、騙されたと思ってAstroの公式ブログテンプレートを試してみてください。

npm create astro@latest -- --template blog

インストールしてビルドした瞬間、その速さとスコアに驚くはずです。

有益なリソース:

次回は「Astro + Tailwind + MDXで作る技術ブログ実践チュートリアル」を書こうと思います。

あなたのブログはどのフレームワークを使っていますか? パフォーマンスに悩みはありますか? ぜひコメントで教えてください。

Next.jsからAstro 5への完全移行ガイド

移行準備からIslandアーキテクチャの実装、SEO設定まで。Lighthouseスコアを68から98へ引き上げるための完全手順。

⏱️ Estimated time: 4 hr

  1. 1

    Step1: Islandアーキテクチャとパフォーマンスの理解

    Islandアーキテクチャの核心:
    • ページ全体は「静的HTMLの海」。
    • インタラクションが必要なコンポーネント(カウンター、フォームなど)だけが「島」として浮かび、独立してJSをロードする。
    • 各島は互いに干渉しない。

    ディレクティブによるJS制御:
    • client:visible(画面に見えたらロード)
    • client:load(ページ読み込みと同時にロード)
    • client:idle(ブラウザが暇になったらロード)

    Server Islands(Astro 5):
    • 静的な外枠を先に返し、動的部分をサーバーが後から注入。
    • キャッシュとパーソナライズの両立が可能。

    実測効果:
    • FCP 2.1秒→0.8秒
    • TTI 4.5秒→1.2秒
    • JSサイズ 280KB→45KB
  2. 2

    Step2: Content Layerによるコンテンツ管理

    Content LayerとLoader:
    • ローカルMarkdown、CMS、APIなどあらゆるソースを一元管理。
    • スキーマ定義によりデータ構造を保証。

    設定例(astro.config.mjs):
    defineCollection({
    loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
    schema: z.object({
    title: z.string(),
    pubDate: z.date(),
    tags: z.array(z.string())
    })
    })

    メリット:
    • Markdownビルド最大5倍高速化
    • MDXビルド2倍高速化
    • メモリ使用量25-50%削減
  3. 3

    Step3: SEO設定の最適化

    Sitemap:
    • npx astro add sitemap
    • astro.config.mjsに site: 'https://...' を必ず記述(相対パス問題回避)。

    Metaタグ:
    • frontmatterでtitle/description/ogImageを管理。
    • Layoutコンポーネントでcanonical URLを設定。

    構造化データ(JSON-LD):
    • 記事、著者、公開日情報をJSON-LDで埋め込み。
    • Schema.org Validatorで検証。

    2025年の重要トレンド:
    • LLM/AI向けの構造化データ。
    • 内部リンク(最低3本)。
    • E-E-A-T(経験・専門性・権威性・信頼性)。
  4. 4

    Step4: 画像最適化の実践

    Astro Imageコンポーネント:
    • CLS防止(サイズ自動推論)。
    • レスポンシブ画像生成(widths指定)。
    • WebP自動変換。

    重要ルール:
    • 画像は public ではなく src フォルダに入れること(最適化の対象にするため)。
    • リモート画像は inferSize を使用。

    効果:
    • 画像容量82%削減(4.2MB→0.8MB)。
    • パフォーマンススコア100点への貢献。
  5. 5

    Step5: View Transitionsの設定

    Astro 5では `ViewTransitions` が `ClientRouter` に名称変更。`<ClientRouter />` をheadに追加するだけで、SPA風の滑らかな遷移を実現。非対応ブラウザへのフォールバックも自動。
  6. 6

    Step6: 移行作業の実行

    移行コマンド `npx @astrojs/upgrade` でAstro 5へ更新。Next.js/Gatsbyからの移行では、まずReactコンポーネントとして移植し、徐々にAstroコンポーネントへ書き換える手法が有効。

FAQ

Next.jsからAstro 5に移行して、どれくらい速くなりましたか?
実測データは以下の通りです:
• ビルド時間:2分 → 18秒(85%短縮)
• Lighthouseスコア:68 → 98(44%向上)
• FCP(初期表示):2.1秒 → 0.8秒(62%高速化)
• TTI(操作可能):4.5秒 → 1.2秒(73%高速化)
• JSバンドルサイズ:280KB → 45KB(84%削減)

特にJSの削減効果が著しく、ブログやドキュメントサイトに最適であることを裏付けています。
Islandアーキテクチャとは何ですか?
ページ全体を静的なHTMLとみなし、インタラクションが必要な部分だけを「島(Island)」として独立させ、そこだけJavaScriptを実行する仕組みです。
例えば `&lt;Counter client:visible /&gt;` と書くと、そのコンポーネントが画面に見えた時だけJSが読み込まれ、実行されます。それ以外のヘッダーやフッターは純粋なHTMLのままです。これにより、不要なJSの読み込みと実行を徹底的に排除できます。
Astro 5のContent Layerのメリットは?
最大のメリットは「データソースの統一管理」と「ビルドパフォーマンス」です。
Loader機能により、ローカルのMarkdownファイルだけでなく、NotionやWordPress、独自APIなどのデータを統一的に扱えます。
また、Astro 5ではビルドプロセスが最適化され、Markdownのビルドが最大5倍、MDXが2倍高速化し、メモリ使用量も大幅に削減されています。
SEO設定で気をつけるべきポイントは?
1. **Sitemapのsite設定**:`astro.config.mjs` に `site` URLを設定しないと、リンクが相対パスになりGoogleに認識されません。
2. **Canonical URL**:重複コンテンツ対策として全ページに設定推奨。
3. **構造化データ(JSON-LD)**:記事や著者の情報を機械可読な形式で提供し、検索エンジンやLLMに正しく内容を伝えること。
4. **画像ALT属性**:基本ですが必須です。
画像最適化で `public` フォルダを使ってはいけないのですか?
使ってはいけないわけではありませんが、**最適化されません**。
Astroの画像最適化機能(サイズ自動調整、フォーマット変換など)を利用するには、画像を `src` ディレクトリ(例:`src/assets/`)に置き、importして使用する必要があります。`public` フォルダの画像は、そのままの状態でブラウザに配信されます。
Astroへの移行手順を教えてください。
1. `npx @astrojs/upgrade` で最新版へ。
2. 他フレームワーク(Next.js等)からの移行の場合、まずはReactコンポーネントをそのままAstroで利用(公式Integrationを使用)。
3. ページの主要部分を `.astro` ファイルに書き換え、Islandアーキテクチャを適用してJSを削減していくのがスムーズです。
もしこれから始めるなら、`npm create astro@latest -- --template blog` で公式テンプレートから始めるのが最も早道です。

6 min read · 公開日: 2025年11月24日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事