返回文章列表
Web

為什麼我選擇 Astro 5 來建立技術 Blog

從 Next.js 遷移到 Astro 5 的心路歷程:Islands Architecture、零 JS 預設、MDX 支援,以及為什麼 Astro 是技術 Blog 的最佳選擇。

為什麼我重建了這個 Blog?

這個 Blog 的前身是用 Next.js 建立的。Next.js 很強大,但對於一個以靜態內容為主的技術 Blog,它顯得過於笨重:

  • 首頁的 JavaScript bundle 超過 180KB
  • Cold start 在 Vercel 邊緣節點上偶爾需要 1-2 秒
  • 每次改一篇文章都要跑完整的 Next.js 建置流程

然後我發現了 Astro,重建之後:

  • JavaScript bundle:< 5KB(幾乎都是首要內容)
  • Lighthouse 分數:100 / 100 / 100 / 100
  • 建置時間:從 45 秒降到 8 秒

Astro 的核心理念:Islands Architecture

Astro 最創新的概念是 Islands Architecture(群島架構)

傳統 SPA 框架把整個頁面當成一個大型 JavaScript 應用。Astro 的思路相反:預設送純 HTML,只在真正需要互動性的地方才載入 JS

---
// 靜態元件:編譯時渲染,零 JavaScript
import StaticHeader from './Header.astro';

// 動態島嶼:客戶端水化
import SearchBox from './SearchBox.tsx';
import CommentSection from './Comments.vue';
---

<StaticHeader />

<!-- 只有這個元件會載入 JS -->
<SearchBox client:load />

<!-- 進入視窗才載入,節省初始資源 -->
<CommentSection client:visible />

client:* 指令決定何時水化(hydrate)元件:

指令時機
client:load頁面載入時立即水化
client:idle瀏覽器空閒時
client:visible元件進入視窗時
client:media媒體查詢符合時
client:only僅客戶端渲染(無 SSR)

Content Collections:類型安全的內容管理

Astro 5 的 Content Collections 是我最喜歡的功能之一。定義 Schema 之後,所有文章的 frontmatter 都會被靜態型別驗證

// src/content/config.ts
import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    category: z.string(),
    tags: z.array(z.string()),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

這樣寫錯 frontmatter 時,建置時就會報錯,而不是到了生產環境才出問題。

MDX:在 Markdown 中嵌入元件

MDX 讓你可以在文章中嵌入 Astro/React 元件:

import { Chart } from '../components/Chart.astro';
import { Callout } from '../components/Callout.astro';

## 效能比較

<Chart data={benchmarkData} type="bar" />

<Callout type="warning">
  以下數據基於 2025 年 1 月的測試環境,不同環境可能有差異。
</Callout>

正文繼續...

效能優化:Astro 預設就很快

Astro 內建幾個效能特性:

自動圖片優化

---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.png';
---

<!-- Astro 自動處理:WebP 轉換、尺寸優化、lazy loading -->
<Image
  src={heroImage}
  alt="Hero image"
  width={1200}
  height={630}
  format="webp"
/>

內建 Sitemap

// astro.config.mjs
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://yoursite.com',
  integrations: [sitemap()], // 自動生成 sitemap.xml
});

部署到 Vercel

Astro 靜態模式部署到 Vercel 非常簡單:

# 安裝
npm create astro@latest my-blog

# 本地開發
npm run dev

# 部署
vercel deploy

Vercel 自動識別 Astro 專案,零設定即可部署。

值得注意的缺點

Astro 不是萬能的,有些場景可能不適合:

  • 高互動性應用:如果你的網站大部分都需要即時互動,Next.js 可能更合適
  • Server Actions:Astro 的 SSR 沒有 Next.js 的 Server Actions 那麼完善
  • 生態系統:相比 Next.js,套件和模板較少

但對於技術 Blog、文件網站、作品集這類以內容為主的網站,Astro 是目前我見過最好的工具。

結語

如果你還在用 Next.js / Gatsby 跑靜態 Blog,建議認真考慮遷移到 Astro。更快、更簡單、更省資源——這才是內容型網站應有的樣子。

這個 Blog 本身就是用 Astro 5 + Tailwind CSS 建立的,原始碼完全開源,歡迎參考。