Next.js静态导出深度解析:如何构建200+页面的高性能工具站
技术架构(更新于 2026年5月17日)
静态导出的核心原理
Next.js 的 output: "export" 模式将整个应用预渲染为纯静态 HTML,无需 Node.js 运行时:
next build (SSG)
↓
遍历所有 generateStaticParams()
↓
为每个 [locale] × [slug] 组合预渲染 HTML
↓
输出到 out/ 目录
↓
上传到 OSS/CDN
SSG vs SSR vs ISR
| 模式 | 需要服务器 | 构建时渲染 | 更新方式 | 适用场景 |
|---|---|---|---|---|
| SSG (export) | 不需要 | ✅ | 重新构建部署 | 内容固定的工具站 |
| SSR | 需要 | ❌ | 每次请求渲染 | 个性化内容 |
| ISR | 需要 | ✅ | 后台增量重渲染 | 频繁更新的内容 |
工具库选择 SSG 的理由:
- 200+ 工具页内容完全静态,无需动态数据
- 部署到阿里云 OSS + CDN,零运维成本
- 首屏 TTFB 极低(CDN 直接返回 HTML)
- 天然支持离线缓存
generateStaticParams 的设计模式
多语言 × 工具页的笛卡尔积
// src/app/[locale]/layout.tsx
export function generateStaticParams() {
return [
{ locale: 'zh-CN' },
{ locale: 'zh-TW' },
{ locale: 'en' },
{ locale: 'ja' },
];
}
// src/app/[locale]/pdf/merge/page.tsx
export function generateStaticParams() {
return [
{ locale: 'zh-CN' },
{ locale: 'zh-TW' },
{ locale: 'en' },
{ locale: 'ja' },
];
}
Next.js 会自动计算 layout.generateStaticParams × page.generateStaticParams 的笛卡尔积,为每个 (locale, path) 组合生成 HTML。
动态路由:博客文章的枚举
// src/app/[locale]/blog/[slug]/page.tsx
export function generateStaticParams() {
return getStaticParamsForAllPosts().map(({ slug, locale }) => ({
locale,
slug,
}));
}
getStaticParamsForAllPosts() 扫描 src/content/blog/ 目录,枚举所有 slug × 可用语言,确保每篇文章的每个语言版本都被预渲染。
构建性能优化
工具库的构建挑战
- 292 个工具页 × 4 语言 = 1168 个 HTML 页面
- 加上博客、分类页等,总计 1300+ 静态页面
- 每个页面需要
getTranslations()加载 i18n 消息
并发控制
// next.config.ts
experimental: {
staticGenerationRetryCount: 2,
...(isCi
? {
staticGenerationMaxConcurrency: 4, // CI: 4 并发
staticGenerationMinPagesPerWorker: 32, // 每 worker 32 页
}
: {
staticGenerationMaxConcurrency: 16, // 本机: 16 并发
staticGenerationMinPagesPerWorker: 8,
}),
}
- CI 环境:GitHub Actions 内存有限,压低并发避免 OOM
- 本机开发:拉高并发加速构建
超时设置
staticPageGenerationTimeout: 180, // 3 分钟
部分工具页(如视频工具)加载 WASM 依赖较多,预渲染耗时可能超过默认 60s。
多语言路由架构
next-intl + App Router 集成
src/i18n/routing-config.ts
→ locales: ['zh-CN', 'zh-TW', 'en', 'ja']
→ localePrefix: 'always' ← 所有 URL 带语言前缀
→ localeDetection: true ← Accept-Language 自动协商
URL 结构
https://www.toolsku.com/zh-CN/pdf/merge/ ← 简体中文
https://www.toolsku.com/en/pdf/merge/ ← 英文
https://www.toolsku.com/zh-CN/blog/pdf-merge-guide/ ← 博客
hreflang 实现
每个页面都注入完整的 hreflang 标签:
<link rel="alternate" hreflang="zh-CN" href="https://www.toolsku.com/zh-CN/pdf/merge/" />
<link rel="alternate" hreflang="zh-TW" href="https://www.toolsku.com/zh-TW/pdf/merge/" />
<link rel="alternate" hreflang="en" href="https://www.toolsku.com/en/pdf/merge/" />
<link rel="alternate" hreflang="ja" href="https://www.toolsku.com/ja/pdf/merge/" />
<link rel="alternate" hreflang="x-default" href="https://www.toolsku.com/zh-CN/pdf/merge/" />
Sitemap 自动发现
工具库的 sitemap.ts 使用文件系统扫描自动发现所有页面:
const pathEntries = discoverLocaleInnerPathsWithFilePath(appDir);
// 自动发现 src/app/[locale]/ 下的所有 page.tsx
跳过动态路由
discoverLocaleInnerPaths 设计上跳过动态段(如 [slug]),因为它们需要参数才能渲染。
对于博客文章,sitemap.ts 额外处理:
const blogSlugs = getAllBlogSlugs();
for (const slug of blogSlugs) {
entries.push({
url: absoluteLocalizedUrl(locale, `/blog/${slug}`),
lastModified: meta.updatedAt,
priority: 0.7,
alternates: { languages },
});
}
CDN 部署架构
资源前缀 (Asset Prefix)
// next.config.ts
assetPrefix: getAssetPrefix(),
// → 生产环境指向 https://toolsku.oss-cn-beijing.aliyuncs.com/public
构建产物中 _next/static/ 下的 JS/CSS 文件都指向 CDN,HTML 由 OSS 直接服务。
部署流程
next build → out/
↓
ossutil cp out/ oss://toolsku/ --recursive
↓
CDN 自动刷新(或等待 TTL)
↓
新版本上线
缓存策略
| 资源类型 | 缓存策略 | 理由 |
|---|---|---|
_next/static/**/*.js |
Cache-Control: max-age=31536000, immutable | 文件名含 hash |
*.html |
Cache-Control: max-age=3600, s-maxage=86400 | 页面可能更新 |
*.wasm |
Cache-Control: max-age=31536000 | WASM 版本稳定 |
i18n/*.json |
Cache-Control: max-age=86400 | 搜索索引定期更新 |
构建流水线
yarn build
→ generate-tools-search-index.mjs ← 生成工具搜索索引
→ generate-tool-clients-public.mjs ← 生成工具客户端数据
→ next build ← SSG 预渲染所有页面
→ 遍历 generateStaticParams()
→ 渲染每个 (locale, path) 组合
→ 输出到 out/
增量构建的挑战
Next.js 静态导出目前不支持增量构建——每次 next build 都会重新渲染所有页面。对于 1300+ 页面的项目,完整构建需要 3-5 分钟。
应对策略:
- CI 环境压低并发减少内存峰值
- 本机开发使用
dev模式(按需渲染,不预生成) - Turbopack 加速开发模式
经验总结
| 决策 | 选择 | 理由 |
|---|---|---|
| 渲染模式 | SSG (export) | 零运维、极低 TTFB |
| 路由模式 | App Router | Server Components、更好的代码分割 |
| 国际化 | next-intl | App Router 原生支持、完善的消息系统 |
| 内容管理 | 代码仓库 (JSON/TS) | 无 CMS 依赖、Git 版本控制 |
| 部署 | OSS + CDN | 国内访问快、零运维 |
纯静态导出是工具类网站的最佳选择——内容固定、访问频繁、需要极致的首屏速度。Next.js App Router + SSG 的组合,让工具库实现了零服务器运维下的高性能部署。
本站提供浏览器本地工具,免注册即可试用 →
#Next.js#SSG#静态导出#CDN#性能优化