sY.zhang.
博客

为什么我用 Astro 而不是 Next.js 写个人博客

从构建产物体积、SEO、内容管理体验到运行时 JS 多寡,对比 Astro 与 Next.js 在内容驱动站点上的取舍。

1 分钟阅读

一个朴素的问题

当我准备把博客从 Next.js 迁到 Astro 时,朋友问我:你都在写 React 了,为什么不直接用 Next.js?

答案其实很简单:我写的是博客,不是应用。

Astro 的默认输出是「零 JavaScript」的 HTML。所有客户端交互都是显式的「岛」(island),需要哪个组件 hydrate 就标 client:load。Next.js 默认 hydrate 整棵树。

构建产物的差距

下面是一份典型博客文章页的对比:

# Next.js (App Router)
dist/app/blog/[slug]/page.js   218 KB

# Astro
dist/blog/[slug]/index.html    38 KB  (含 inline CSS)

差距主要来自框架运行时。React + Next 路由 + RSC 序列化层,最低开销就在那里。Astro 把这些全部剥掉,只在标记了 client: 的组件上才注入 React 运行时。

Content Collections 是真正的杀手锏

Next.js 写博客文章,通常要在 getStaticProps 里手动 fs.readdirgray-matter 解析。Astro 直接给你一套类型安全的 schema:

// src/content.config.ts
const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    pubDate: z.coerce.date(),
    tags: z.array(z.string()).default([]),
  }),
});

frontmatter 写错会在构建时报错,不用再担心上线后才发现某篇文章日期格式错了。

MDX 原生支持

技术博客的杀手锏是在文章里嵌交互组件。比如下面这个可点击的 demo:

<Counter client:load />

Astro 的 MDX 集成是构建时把组件编译进 HTML,运行时按需 hydrate。Next.js 也能做,但需要更小心的 'use client' 边界管理。

什么时候不用 Astro

  • 需要 SSR 动态数据(用户登录态、实时数据)
  • 全应用本身就是 SPA(仪表盘、编辑器)
  • 重度使用 React Server Components 的能力

如果是这些场景,Next.js 仍然是更好的选择。Astro 是为内容优先的站点设计的,它在这个领域里几乎没有对手。

结论

如果站点 80% 是内容、20% 是交互,选 Astro。 如果反过来,选 Next.js。

简单粗暴,但适用。