Astro 靜態網站框架:零 JavaScript 的極致效能
Astro 靜態網站框架:零 JavaScript 的極致效能
在追求 Web 效能的道路上,Astro 提出了一個大膽的理念:預設不傳送任何 JavaScript 到瀏覽器。只有在真正需要互動性的地方,才選擇性地注水(hydrate)客戶端元件。這個「島嶼架構(Islands Architecture)」讓 Astro 在效能測試中幾乎橫掃一切。
Astro 的核心理念
傳統的 SPA 框架(React、Vue)把所有 JavaScript 打包後送到瀏覽器,即使頁面大部分是靜態內容。Astro 反其道而行:
傳統 SPA:整頁 JavaScript → 瀏覽器執行 → 渲染畫面
Astro:伺服器渲染 HTML → 瀏覽器直接顯示 → 只在需要時載入 JS安裝與建立專案
# 建立新專案
npm create astro@latest my-blog
# 互動式設定精靈會詢問:
# - 使用哪個模板(空白、部落格、文件...)
# - 是否使用 TypeScript
# - 是否安裝依賴
cd my-blog
npm run devAstro 檔案語法
.astro 檔案分為兩個部分:
---
// Component Script(在伺服器端執行,類似 frontmatter)
import Header from '../components/Header.astro';
import BlogPost from '../components/BlogPost.astro';
// 可以使用任何 Node.js API
const posts = await fetch('https://api.example.com/posts').then(r => r.json());
const title = "我的部落格";
---
<!-- Component Template(HTML + JSX 語法混合)-->
<html lang="zh-TW">
<head>
<meta charset="utf-8" />
<title>{title}</title>
</head>
<body>
<Header />
<main>
{posts.map(post => (
<BlogPost title={post.title} url={`/posts/${post.slug}`} />
))}
</main>
</body>
</html>內容集合(Content Collections)
Astro 的內容集合是管理 Markdown 文章的強大功能:
// 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.date(),
author: z.string().default('匿名'),
tags: z.array(z.string()).default([]),
cover: z.string().optional(),
}),
});
export const collections = { blog };---
title: "我的第一篇文章"
description: "這是文章的描述"
pubDate: 2026-03-04
author: "王小明"
tags: ["JavaScript", "Astro"]
---
# 我的第一篇文章
這是文章內容...---
// pages/blog/index.astro
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
const sortedPosts = posts.sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
---
<main>
{sortedPosts.map(post => (
<article>
<h2><a href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
<p>{post.data.description}</p>
<time>{post.data.pubDate.toLocaleDateString('zh-TW')}</time>
</article>
))}
</main>島嶼架構(Islands)
這是 Astro 最獨特的功能——你可以在靜態頁面中嵌入互動式的 React/Vue/Svelte 元件:
# 安裝框架整合
npx astro add react
npx astro add vue---
// 混合使用多個框架的元件!
import ReactCounter from '../components/Counter.tsx';
import VueSearch from '../components/Search.vue';
import StaticCard from '../components/Card.astro'; // 靜態元件,無 JS
---
<main>
<!-- 靜態元件:不傳送任何 JS -->
<StaticCard title="靜態卡片" />
<!-- 立即注水:頁面載入後立即互動 -->
<ReactCounter client:load />
<!-- 可見時注水:進入視窗才載入 JS -->
<VueSearch client:visible />
<!-- 閒置時注水:瀏覽器閒置時載入 -->
<ReactCounter client:idle />
<!-- 媒體查詢注水:符合條件時載入 -->
<ReactCounter client:media="(max-width: 768px)" />
</main>路由系統
Astro 使用基於檔案的路由:
src/pages/
├── index.astro → /
├── about.astro → /about
├── blog/
│ ├── index.astro → /blog
│ └── [slug].astro → /blog/:slug(動態路由)
└── api/
└── posts.ts → /api/posts(API 端點)動態路由
---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>API 端點
// src/pages/api/posts.ts
import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';
export const GET: APIRoute = async () => {
const posts = await getCollection('blog');
return new Response(JSON.stringify(
posts.map(p => ({ slug: p.slug, title: p.data.title }))
), {
headers: { 'Content-Type': 'application/json' },
});
};部署
Astro 可以部署為靜態網站或 SSR 應用:
# 靜態部署(預設)
npm run build
# 輸出到 dist/ 資料夾,可部署到任何靜態托管服務// astro.config.mjs
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'server', // 啟用 SSR
adapter: vercel(),
});效能表現
Astro 網站的典型 Lighthouse 分數:
| 指標 | Next.js(SPA) | Astro |
|---|---|---|
| Performance | 70-85 | 95-100 |
| LCP | ~2.5s | ~0.8s |
| TBT | ~300ms | ~0ms |
| JS 大小 | 200-500KB | 0-20KB |
適用場景
最適合 Astro 的場景:
- 部落格、技術文件、行銷頁面
- 內容導向的網站
- 追求極致 SEO 和 Core Web Vitals 的專案
不適合 Astro 的場景:
- 高度互動的 Web App(如 Figma、Google Docs)
- 需要複雜客戶端狀態管理的應用
總結
Astro 重新定義了靜態網站生成器的可能性。它讓你用熟悉的 React/Vue 語法開發,卻能輸出接近純 HTML 的高效能頁面。對於內容導向的網站,Astro 幾乎是目前最佳的選擇,兼顧了開發體驗和最終效能。
分享這篇文章