🏝️ Islands 架构

Astro 开创的前端架构模式,选择性水合交互组件:

🎯 核心思想

  • 页面默认渲染为静态 HTML
  • 只有交互组件加载 JavaScript
  • 每个岛屿独立水合,不阻塞其他
  • 并行加载,优先级可控

Client 指令

指令说明
client:load页面加载时立即水合
client:idle浏览器空闲时水合
client:visible进入视口时水合
client:media匹配媒体查询时水合
client:only跳过服务端渲染

📦 零 JS 默认

Astro 默认不发送任何 JavaScript 到客户端:

astro
---
// 这个组件不会发送任何 JS 到客户端
const items = ['苹果', '香蕉', '橙子'];
---

<ul>
  {items.map(item => <li>{item}</li>)}
</ul>

对比传统框架

框架默认 JS水合方式
Astro0 KB选择性
Next.js~80 KB全页水合
Gatsby~120 KB全页水合

🎨 多框架支持

在同一个项目中混用不同框架:

astro
---
import ReactWidget from './ReactWidget.jsx';
import VueWidget from './VueWidget.vue';
import SvelteWidget from './SvelteWidget.svelte';
---

<!-- React 组件 -->
<ReactWidget client:visible />

<!-- Vue 组件 -->
<VueWidget client:idle />

<!-- Svelte 组件 -->
<SvelteWidget client:load />

📚 Content Collections

类型安全的内容管理:

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

const blog = defineCollection({
  schema: z.object({
    title: z.string(),
    date: z.date(),
    tags: z.array(z.string()),
  }),
});

export const collections = { blog };
astro
---
import { getCollection } from 'astro:content';

const posts = await getCollection('blog');
---

{posts.map(post => (
  <article>
    <h2>{post.data.title}</h2>
    <p>{post.data.date}</p>
  </article>
))}

🔄 View Transitions

页面切换动画,无需额外配置:

astro
---
import { ViewTransitions } from 'astro:assets/transitions';
---

<html>
  <head>
    <ViewTransitions />
  </head>
  <body>
    <!-- 页面切换时自动平滑过渡 -->
  </body>
</html>