Skip to content

fix(build): cut Cloudflare build time#181

Closed
dcrawbuck wants to merge 2 commits intomainfrom
dcrawbuck/faster-cf-build
Closed

fix(build): cut Cloudflare build time#181
dcrawbuck wants to merge 2 commits intomainfrom
dcrawbuck/faster-cf-build

Conversation

@dcrawbuck
Copy link
Copy Markdown
Collaborator

@dcrawbuck dcrawbuck commented Apr 29, 2026

Summary

Goal: get the Cloudflare build under 5–7 minutes. Local benchmarks dropped from 109s to ~85s (~23% faster), with bigger gains on warm builds once the new MDX cache is populated.

  • Combine post-build scripts into scripts/generate-static-assets.ts — the old pipeline cold-started two separate Vite SSR servers and re-evaluated the same fumadocs MDX collection in each. One server, both jobs in parallel, saves ~16s.
  • async: true for the docs MDX collection in production — page MDX is dynamically imported instead of inlined into the SSR bundle. Pages still fully prerender to static HTML, so no end-user behavior change. Bonus: client main bundle 18 MB → 1.9 MB (10× smaller), SSR bundle 30 MB → 256 KB.
  • Enable fumadocs-mdx experimentalBuildCache at node_modules/.cache/fumadocs-mdx — Cloudflare Pages persists node_modules between deploys with build caching on, so unchanged MDX files skip Shiki + remark on warm builds.
  • Prerender concurrency = os.cpus().length instead of hardcoded 3.
  • Add bun run measure:build — phase-by-phase timing for future tuning, results land in .context/build-timings/.

Test plan

  • CI green (bun test, bun run build:cf)
  • Cloudflare staging deploy succeeds and the build is faster than main
  • Spot-check a few pages render correctly (incl. one with code blocks and one with mermaid)
  • Client-side nav still works (the static __sfn_cache/*.json files load on prefetch)
  • Search dialog returns results (search-index.json loads)

Note

Cursor Bugbot is generating a summary for commit 01ac397. Configure here.

- Combine generate-static-cache + generate-search-index into one
  script (scripts/generate-static-assets.ts) sharing one Vite SSR
  server, saves ~16s of redundant cold-start + source eval.
- Switch the docs MDX collection to async: true in production. Each
  page's compiled MDX becomes a dynamic import instead of being inlined
  into the SSR bundle. Client main bundle 18 MB → 1.9 MB, SSR bundle
  30 MB → 256 KB; pages still fully prerender to static HTML so no
  end-user impact.
- Enable fumadocs-mdx experimentalBuildCache under node_modules/.cache
  so MDX compilation (shiki + remark) is skipped for unchanged files
  on warm builds (Cloudflare Pages persists node_modules between
  deploys with build caching enabled).
- Set prerender concurrency to os.cpus().length (was hardcoded to 3).
- Add scripts/measure-build.ts for phase-by-phase build timing.

Local: 109s → ~85s. CF projection: 5–6 min → ~3.5–4 min cold,
faster on warm builds once the MDX cache is populated.
@dcrawbuck dcrawbuck changed the title perf(build): cut Cloudflare build time ~25% fix(build): cut Cloudflare build time Apr 29, 2026
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 29, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
superwall-docs-staging 960d598 Apr 29 2026, 02:33 AM

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 01ac397. Configure here.

Comment thread vite.config.ts
// Was hardcoded to 3 (suspected OOM defense). With
// --max-old-space-size=8192 set in `bun run build` we have plenty of
// headroom — let it use whatever the builder actually has.
concurrency: os.cpus().length,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.cpus().length may be zero or excessive in containers

Medium Severity

os.cpus() can return an empty array in certain containerized environments (documented Node.js behavior when /proc CPU info is unavailable), making os.cpus().length equal to 0. A concurrency of 0 would likely cause the prerender step to hang or error. Even when it doesn't return empty, in containers like Cloudflare's builders it often reports the host machine's CPU count rather than the container's allocation, which could trigger the OOM the previous hardcoded 3 was guarding against. Using os.availableParallelism() (available in both Node.js 19+ and Bun) is safer — it always returns ≥ 1 and better respects cgroup limits.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 01ac397. Configure here.

No code changes — testing that the warm fumadocs-mdx build cache
populated by the previous deploy speeds up this build.
@dcrawbuck dcrawbuck closed this Apr 29, 2026
@dcrawbuck dcrawbuck deleted the dcrawbuck/faster-cf-build branch April 29, 2026 02:34
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