833 字
4 分钟
Astro Fuwari 博客 Vercel 构建 OOM 优化实战
问题背景
我的博客使用 Astro 构建,部署在 Vercel 上。随着文章数量增长到 500+ 篇,遇到了构建失败的问题:
ELIFECYCLE Command failed with exit code 137.Error: Command "pnpm run build" exited with 137

Exit code 137 意味着进程被 SIGKILL 终止,通常是因为内存不足 (OOM)。Vercel 免费版提供 8GB RAM,理论上应该足够,但实际构建时内存峰值过高。
问题分析
通过分析构建日志和代码,我发现了几个内存瓶颈:
1. getStaticPaths 传递完整 entry 对象
这是最关键的问题。原来的代码:
export async function getStaticPaths() { const posts = await getSortedPosts(); return posts.map((entry) => ({ params: { slug: entry.id }, props: { entry }, // 传递完整 entry 对象! }));}这意味着 500 篇文章的完整内容都被存储在路由 props 中,同时占用内存。
2. 默认无限制并发构建
Astro 默认会尽可能多地并行构建页面,在内存受限环境下会导致峰值过高。
3. HTML 压缩消耗额外内存
虽然 HTML 压缩可以减少文件大小,但在构建时需要额外内存。而 CDN(如 Cloudflare、Vercel)会自动使用 Brotli 压缩传输,本地压缩意义不大。
优化方案
1. 核心优化:getStaticPaths 只传递必要数据
export async function getStaticPaths() { const posts = await getSortedPosts();
// 只传递必要的导航数据 return posts.map((entry) => ({ params: { slug: entry.id }, props: { slug: entry.id, prevSlug: entry.data.prevSlug, prevTitle: entry.data.prevTitle, nextSlug: entry.data.nextSlug, nextTitle: entry.data.nextTitle, }, }));}
// 在渲染时按需获取完整内容const { slug, prevSlug, prevTitle, nextSlug, nextTitle } = Astro.props;const entry = await getEntry("posts", slug);const { Content } = await render(entry);这个优化将 getStaticPaths 阶段的内存占用减少了 90% 以上。
2. 增加 Node.js 内存限制
{ "scripts": { "build": "NODE_OPTIONS='--max-old-space-size=7168' astro build" }}Node.js 默认堆内存限制约 2-4GB,显式设置为 7GB 可以充分利用 Vercel 的 8GB RAM。
3. 限制构建并发
export default defineConfig({ build: { concurrency: 2, // 限制并发构建 },});有趣的是,测试发现 concurrency: 2 比无限制更快:
concurrency: 2:2m 19s ✅- 无限制:3m 45s ❌
过多并发会导致资源竞争,反而变慢。
测试方法:
- 首先concurrency: 2
- 运行构建并计时
- 先增加到4,再增加到6,最后增加到8
- 使用最快设置
- 重要提示:并非越多越好!案例研究发现,在12核系统中,4个CPU是最佳选择。

4. 禁用 HTML 压缩
export default defineConfig({ compressHTML: false, // 让 CDN 处理压缩});CDN 使用 Brotli 压缩(比 gzip 更高效),本地 HTML 压缩的收益被覆盖,不如省下这部分内存和时间。
5. 升级构建目标
// astro.config.mjs - vite 配置vite: { build: { target: 'es2022', // 减少代码转译 },}6. 修复 Expressive Code 重复主题
// 修复前(bug)themes: [theme, theme], // 重复了
// 修复后themes: [theme],优化效果
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 构建结果 | OOM 失败 | 成功 ✅ |
| 构建时间 | - | 2m 19s |
| 内存占用 | 超过 8GB | 正常范围 |
总结
对于大规模 Astro 博客的构建优化,最重要的是:
- getStaticPaths 只传递必要数据 - 这是核心优化
- 合理的并发限制 - 不是越多越好
- 利用 CDN 压缩 - 本地压缩可以省略
- 充分利用可用内存 - 设置 NODE_OPTIONS
这些优化不仅解决了 OOM 问题,还让构建更快更稳定。
参考
Astro Fuwari 博客 Vercel 构建 OOM 优化实战
https://catcat.blog/2025/12/astro-vercel-oom-optimization.html