為什麼我重建了這個 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 建立的,原始碼完全開源,歡迎參考。