






















天下武功,唯快不破!最近优化博客搞得有点魔怔了。原本的计划是用 Astro 彻底重构整个项目,毕竟 Astro 在静态站点生成方面的优势实在太明显了。但在深入了解之后,我发现 Next.js 其实也能实现几乎相同的效果,而且迁移成本更低。本文就来分享一下这次 Next.js 静态化改造的完整过程。
其实原因很简单:性能和成本。目前的博客使用 Next.js 的 SSG(静态站点生成)模式,但仍然依赖 Next.js 的服务端运行时。这意味着:
而 Astro 是纯静态站点生成器,输出的是纯粹的 HTML/CSS/JS,可以部署到任何免费的静态托管服务上,真正的零成本。这让我心动了很久。
在准备切换到 Astro 之前,我仔细研究了 Next.js 的静态导出功能。结果 Next.js 完全可以实现和 Astro 几乎相同的静态化效果。
| 特性 | Astro | Next.js 静态导出 |
|---|---|---|
| 静态 HTML 输出 | ✅ 默认 | ✅ 支持(output: 'export') |
| 零运行时成本 | ✅ 纯静态 | ✅ 纯静态 |
| 免费托管 | ✅ 任何静态服务 | ✅ 任何静态服务 |
| React 生态 | ❌ 需要集成 | ✅ 原生支持 |
| 迁移成本 | ❌ 需要重写大部分代码 | ✅ 只需修改配置 |
| 学习曲线 | ❌ 新框架、新语法 | ✅ 无需学习 |
| 现有组件复用 | ❌ 需要改写 | ✅ 100% 复用 |
看到这些对比,还切换什么Astro?Next.jsy一样挺香啊。
最关键的是,性能差异几乎可以忽略不计。静态导出后的 Next.js 博客,Lighthouse 分数可以轻松达到 95+,和 Astro 几乎没有区别。
首先,在 next.config.mjs 中添加静态导出配置:
export default {
output: 'export', // 启用静态导出
trailingSlash: true, // 添加尾随斜杠
images: {
unoptimized: true, // 禁用图片优化(静态导出必需)
},
// ... 其他配置保持不变
}
在所有使用 getStaticProps 的页面中,添加 revalidate: false:
export async function getStaticProps() {
// ... 数据获取逻辑
return {
props: { /* 数据 */ },
revalidate: false, // 禁用 ISR,纯静态生成
};
}
如果使用了 App Router(如 RSS Feed、Sitemap 等),需要添加:
export const dynamic = 'force-static';
搜索功能遇到了一个有趣的问题。原本使用动态路由 /search/[query],但静态导出后无法预生成所有可能的搜索词路由。
解决方案是将搜索功能改为纯客户端实现:
// 在 /search 页面中
export async function getStaticProps() {
const allPosts = getAllPosts(); // 获取所有文章数据
return {
props: { allPosts }, // 传递给客户端
revalidate: false,
};
}
// 客户端实时搜索
const [searchQuery, setSearchQuery] = useState('');
const [filteredPosts, setFilteredPosts] = useState([]);
useEffect(() => {
if (searchQuery.trim()) {
const filtered = allPosts.filter(post =>
post.title?.toLowerCase().includes(searchQuery.toLowerCase())
);
setFilteredPosts(filtered);
}
}, [searchQuery, allPosts]);
这样既解决了静态导出的问题,又提供了更好的用户体验(实时搜索)。
为了方便测试,在 package.json 中添加了预览脚本:
{
"scripts": {
"preview": "python -m http.server 8000 --directory out"
}
}
完成配置后,运行构建命令:
npm run build
构建成功后,会看到类似这样的输出:
Route (pages)
┌ ● / (920 ms)
├ ● /blog/[id] (374947 ms)
│ ├ /blog/20260206132113 (1578 ms)
│ └ [+365 more paths]
├ ● /tags/[tag] (123863 ms)
│ ├ /tags/react (1128 ms)
│ └ [+148 more paths]
└ ● /search (920 ms)
构建产物会输出到 out 目录,包含所有生成的静态文件。
现在部署方式完全和 Astro 一样了:
npm run build # 构建
npm run preview # 预览(访问 http://localhost:8000)
可以选择任何免费的静态托管服务:
最棒的是,如果你之前已经部署到 Vercel,部署流程完全不需要改变!只需要 git push,Vercel 会自动识别静态导出配置并正确部署。
静态导出后的性能表现:
和 Astro 几乎没有区别!
这次静态化改造让我学到了很多:
最终我选择了 Next.js 静态化,而不是 Astro。原因很简单:
Astro 依然是一个优秀的框架,但对于已经使用 Next.js 的项目来说,静态导出可能是更务实的选择。
静态化只是第一步,接下来还可以考虑:
但目前的性能已经非常好了,这些可以作为后续的优化方向。
总结:有时候,最好的解决方案不是追逐最新的技术,而是充分利用现有工具的潜力。Next.js 静态导出让我在不改变技术栈的情况下,获得了和 Astro 几乎相同的性能优势,这是最完美的选择。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。