Skip to content

perf(homepage): 首页 SSG 化,剩 25% Vercel CPU 归零#332

Merged
longsizhuo merged 3 commits intomainfrom
perf/homepage-ssg
May 6, 2026
Merged

perf(homepage): 首页 SSG 化,剩 25% Vercel CPU 归零#332
longsizhuo merged 3 commits intomainfrom
perf/homepage-ssg

Conversation

@longsizhuo
Copy link
Copy Markdown
Member

背景

i18n PR (#330) 让 docs 全量 SSG,剩首页(占 30 天 Vercel Fluid CPU ~25%)仍 ƒ Dynamic。原因:

// app/[locale]/page.tsx
export default async function HomePage(...) {
  const homepageEvents = await fetchHomepageEvents();  // ← server fetch
  ...
}

Hero 内的 HotDocsPreviewActivityTicker 也是 async server component,server fetch backend 同样阻挡 SSG。

改造

1. 新建两条 ISR 代理 API

Route revalidate 用途
/api/public/homepage-events 5min 首页活动数据(FloatWindow / ActivityTicker)
/api/public/top-docs 5min 本周最热文档(HotDocsPreview)

server-side 调后端,浏览器调自家代理(同源无 CORS,BACKEND_URL 不暴露),revalidate 让 Next.js Data Cache + 浏览器 Cache-Control 双保险,最多每 5min 一次后端调用。

2. 三个组件改 client

  • ActivityTicker async server → client + useEffect fetch
  • HotDocsPreview async server → client;翻译从 getTranslationsuseTranslations(client hook);fetch 期间显示 Skeleton
  • FloatWindow 从 props 接 event 改为自取

3. page.tsx 纯静态

  • await fetchHomepageEvents() + 删 prop 传递
  • export const dynamic = 'force-static' + setRequestLocale 双保险

build 验证

├ ● /[locale]                                ← 从 ƒ 变 ●
│ ├ /zh
│ └ /en
├ ○ /api/public/homepage-events  5m  1y
├ ○ /api/public/top-docs         5m  1y

322 → 361 prerendered routes(多了 /zh、/en、+ 两条 ISR API)。

预期收益

  • Vercel Fluid CPU 月用量:~3h51m → ~0.5-1h(仅 admin / events / feed / u/[username] 等数据动态路由产生)
  • 首页 TTFB:之前 1.7-2s(前后端串联)→ 静态 HTML 直接 serve
  • LCP / Core Web Vitals 改善

副作用

  • 首屏 ActivityTicker / HotDocsPreview 不立即出现,等 hydrate 后 fetch 显示
  • ticker 不是 LCP 元素,HotDocsPreview 有 Skeleton 占位避免 CLS,可接受

Test plan

  • preview 部署 /zh 看 FloatWindow 1-2s 内显示
  • HotDocsPreview Skeleton → 真实数据切换无 layout shift
  • ActivityTicker 在 hydrate 后出现
  • Vercel Observability 一周后看 /[locale] 的 invocation 数应该接近 0
  • 直接访问 /api/public/homepage-events 返回正常 JSON

github-actions Bot added 2 commits May 6, 2026 15:27
i18n PR 收尾。app/[locale]/page.tsx 之前 await fetchHomepageEvents()
让首页钉成 ƒ Dynamic(任何 server fetch 都阻挡 SSG),首页占 30 天
Vercel Fluid CPU ~25%。

改造:
- 新建 /api/public/homepage-events 和 /api/public/top-docs ISR 代理
  (revalidate=300,浏览器 Cache-Control 5min),让 server 端的 backend
  fetch 集中在两条静态化的 API route 里,最多每 5min 命中一次
- ActivityTicker 从 async server component 改 client,useEffect 自取
- HotDocsPreview 同样改 client(翻译用 useTranslations 替代
  getTranslations),Skeleton 在 fetch 期间显示
- FloatWindow 从 props 接收 event 改为自取,page.tsx 不再传
- app/[locale]/page.tsx 加 force-static + setRequestLocale,纯静态

build 表(验证):
  / → ● /[locale]
        ├ /zh
        └ /en
  /api/public/homepage-events → ○ Static (5m revalidate)
  /api/public/top-docs        → ○ Static (5m revalidate)

预期 Vercel Fluid CPU 从月 ~3h51m 降到月 0.5-1h(仅 admin/events/feed
等动态路由产生)。
Copilot AI review requested due to automatic review settings May 6, 2026 15:35
@vercel
Copy link
Copy Markdown

vercel Bot commented May 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
involutionhell-github-io Ready Ready Preview, Comment May 6, 2026 5:12pm
website-preview Ready Ready Preview, Comment May 6, 2026 5:12pm

补两条 i18n 收尾的零碎:

1. app/[locale]/page.tsx 加 generateMetadata
   覆盖 root layout 默认 alternates,给首页输出当前 locale 的 canonical
   (/zh 或 /en),并且 hreflang 三向声明(zh-CN / en-US / x-default)。
   每个 locale 各自 canonical,不再共享 root 的 fallback。

2. dev_docs/i18n_url_routing.md 加「如何加新 user-facing 路由」章节
   贴出 page.tsx + generateMetadata 的 boilerplate,列出 5 条容易踩的坑:
   - setRequestLocale 排序
   - @/i18n/navigation vs next/navigation 选错的后果
   - components 不在 [locale] 下
   - server fetch 让 page 退回 dynamic 的应对
   - layout 嵌套也要逐层 setRequestLocale

后续加 page 直接抄就能保证 SSG + i18n 一起对。
@longsizhuo longsizhuo merged commit 2425d9a into main May 6, 2026
8 checks passed
@longsizhuo longsizhuo deleted the perf/homepage-ssg branch May 6, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant