技术

Astro 与 Next.js 的选择

在什么场景下选择 Astro 或 Next.js?深入对比两个框架的优劣

Astro 与 Next.js 的选择

在 GoCode Monorepo 中,我们同时使用了 Astro 和 Next.js。这不是重复造轮子,而是根据不同场景选择最合适的工具。

快速对比

特性AstroNext.js
主要用途内容驱动的网站交互式 Web 应用
渲染方式默认零 JS混合 SSR/CSR
性能极致轻量优秀但较重
学习曲线平缓中等
生态系统快速增长成熟丰富

Astro 的优势

1. 零 JavaScript 默认

Astro 默认不发送任何 JavaScript 到客户端,只有在需要交互时才加载。

---
// 这部分代码只在服务器运行
const posts = await fetchPosts();
---

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

2. 岛屿架构

可以精确控制哪些组件需要客户端交互:

---
import InteractiveWidget from './InteractiveWidget';
import StaticContent from './StaticContent';
---

<!-- 静态内容,无 JS -->
<StaticContent />

<!-- 只有这个组件会加载 JS -->
<InteractiveWidget client:load />

3. 多框架支持

可以在同一个项目中混用 React、Vue、Svelte 等:

---
import ReactButton from './ReactButton.jsx';
import VueCounter from './VueCounter.vue';
---

<ReactButton client:load />
<VueCounter client:visible />

4. 内容集合

内置的内容管理系统,完美适配 Markdown/MDX:

import { getCollection } from 'astro:content';

const blogPosts = await getCollection('blog');

Next.js 的优势

1. 强大的路由系统

App Router 提供了灵活的路由和布局系统:

// app/blog/[slug]/page.tsx
export default function BlogPost({ params }: { params: { slug: string } }) {
  return <article>...</article>;
}

2. Server Components

React Server Components 让你可以在服务器端直接访问数据:

async function BlogList() {
  const posts = await db.posts.findMany();

  return (
    <div>
      {posts.map(post => (
        <PostCard key={post.id} post={post} />
      ))}
    </div>
  );
}

3. API Routes

内置的 API 路由,方便构建全栈应用:

// app/api/posts/route.ts
export async function GET() {
  const posts = await db.posts.findMany();
  return Response.json(posts);
}

4. 丰富的生态

大量的第三方库和工具专门为 Next.js 优化。

在 GoCode 中的应用

使用 Astro 的场景

  1. site-astro(当前主应用)
    • 门户 + 知识库统一站点
    • 内容为主,交互适中
    • SEO 与加载性能优先

使用 Next.js 的场景

  1. 未来的 Dashboard / 业务后台
    • 管理后台
    • 实时数据
    • 复杂状态管理

性能对比

首屏加载

Astro 内容站(site-astro):

  • HTML: 15KB
  • CSS: 8KB
  • JS: 0KB (无交互时)
  • 总计: ~23KB

Next.js 交互应用(典型场景):

  • HTML: 18KB
  • CSS: 12KB
  • JS: 85KB (包含 React runtime)
  • 总计: ~115KB

构建时间

对于相同内容量:

  • Astro: ~2s
  • Next.js: ~5s

最佳实践

1. 根据内容类型选择

  • 静态内容 → Astro
  • 动态应用 → Next.js

2. 共享组件库

两个框架都可以使用 @repo/ui 组件库,保持视觉一致性。

3. 统一的内容源

所有内容存储在 gocode-context,两个框架都可以访问。

4. 渐进增强

从 Astro 开始,需要更多交互时再考虑 Next.js。

结论

Astro 和 Next.js 不是竞争关系,而是互补的工具。在 GoCode 中:

  • Astro 负责内容展示,追求极致性能
  • Next.js 负责应用逻辑,提供丰富交互

选择合适的工具,而不是最流行的工具,这就是 GoCode 的理念。

参考资源