我的個人網站用 Next.js 寫了將近兩年。它能用,但每次打開專案都有一種奇怪的不適感——一個靜態展示網站,卻帶著 React runtime、hydration、_app.tsx、_document.tsx,還有一堆我根本用不到的機制。
最後我決定重寫。用 Astro。以下是這個過程。
為什麼要換
Next.js 是一個優秀的框架。對於需要動態資料、身份驗證、複雜路由的應用來說,它依然是我的首選。但個人網站不是應用。
舊網站的問題很具體:
JavaScript bundle 太重。 一個沒有任何互動的頁面,卻要下載完整的 React runtime。使用者打開頁面,瀏覽器執行了大量 JavaScript,然後什麼都沒有發生——因為頁面根本沒有需要 JavaScript 的地方。
pages/ 目錄越來越亂。 _app.tsx、_document.tsx、getStaticProps、getStaticPaths——每個頁面都要思考這些,即使只是一個純靜態的關於頁。
維護感覺像在維護一個產品。 依賴項繁多,eslint、prettier、各種 Chakra UI 的配置。每次 npm install 都是一次小小的冒險。
為什麼選 Astro
Astro 的核心主張很簡單:預設零 JavaScript。只有你明確需要互動的部分才會送出 JavaScript,其餘全部是靜態 HTML。
對個人網站來說,這個哲學完全對齊。
另外幾個吸引我的點:
- Content Collections:內建的 Blog 文章管理,有型別安全的 frontmatter schema,不需要自己處理 Markdown
- Islands Architecture:需要互動的地方用 SolidJS 或 React,其他地方不帶任何框架
.astro語法:component-scoped CSS、直接在 frontmatter 寫 server logic,感覺很乾淨- Cloudflare 適配器:一行指令部署到 Cloudflare Workers,不需要思考 Node.js server
遷移過程
內容結構
舊版的頁面內容是散落在各個 .tsx 檔案裡的 JSX 字串。沒有 CMS,沒有 Markdown,就是硬寫在 component 裡。
新版用 Astro 的 Content Collections:
src/content/blog/posts/ ├── nextjs-to-astro.mdx ├── vibe-coding.mdx └── rss-still-matters.mdx每篇文章有 frontmatter,schema 在 content.config.ts 定義。加一篇文章就是加一個 .mdx 檔案,完全不需要動程式碼。
樣式
舊版用 Chakra UI 加自訂的 SCSS。遷移後全部換成 Tailwind CSS v4 加 CSS 自訂變數。
設計 token 統一定義在 :root:
:root { --color-base: #0f0f0f; --color-cyan: #22d3ee; --font-mono: "JetBrains Mono", monospace;}不需要任何 JavaScript,不需要 theme provider,不需要 useColorMode。主題切換就是在 <html> 上加 .light class,CSS 變數自動覆蓋。
路由
Next.js 的 pages/ 路由對應到 Astro 的 src/pages/ 幾乎是一比一。差別在於 Astro 的路由檔案是 .astro,而不是 .tsx。
動態路由的語法也差不多:
Next.js: pages/blog/[slug].tsxAstro: src/pages/blog/[...slug].astro用 [...slug] 而不是 [slug] 是因為 Content Collections 的文章 ID 包含目錄路徑(posts/hello-world),需要 catch-all route。
部署
舊版部署在 Vercel,完全自動,沒什麼好說的。
新版的目標是 Cloudflare Pages。設定 @astrojs/cloudflare 適配器,加上 GitHub Actions workflow,每次 push 到 main 自動部署。
- name: Build run: bun run build
- name: Deploy to Cloudflare Pages uses: cloudflare/wrangler-action@v3 with: command: pages deploy dist --project-name=niskan516-space遷移後的差異
幾個具體的變化:
| Next.js | Astro | |
|---|---|---|
| JavaScript(首頁) | ~120KB | ~15KB |
| 依賴項數量 | 47 | 18 |
| 冷啟動建置時間 | ~25s | ~4s |
| 部署平台 | Vercel | Cloudflare Pages |
| 套件管理器 | pnpm | Bun |
JavaScript 的差距最明顯。舊版首頁送出的 JavaScript 幾乎全都是框架本身,沒有任何業務邏輯。
值不值得
對個人網站來說,完全值得。
重寫本身花了一個下午(加上 Claude Code 的協助,速度快了很多)。現在的架構比舊版簡單太多——沒有多餘的抽象,每個部分都有明確的理由存在。
如果你有一個主要是靜態內容的網站,但還在用 React 框架,可以認真考慮 Astro。不是所有網站都需要一個 SPA 框架——有時候靜態 HTML 就是正確答案。