Raxx · internal docs

internal · gated

Antlers Next.js — Phase 2 Performance Baseline

Date: 2026-05-27
Site measured: https://staging-nextjs.raxx.app/
Issue: #2881
Method: Lighthouse CLI 13.3.0 (--only-categories=performance, headless Chrome, simulated 4G throttling), curl TTFB (3 trials each, median reported)
CRA comparison source: local build at frontend/trademaster_ui/build/ (raxx.app is CF Access-gated; Lighthouse redirected to Access login page and cannot measure app)


1. Bundle Size

1a. Next.js scaffold (live staging — per-chunk)

Asset Raw (B) Gzip (B) Gzip (KiB) Notes
fd9d1056-*.js 172,834 53,802 52.5 Largest vendor chunk (React runtime + router)
polyfills-*.js 112,594 39,503 38.6 Next.js polyfills
30-be3f1d*.js 124,584 31,901 31.2 Framework chunk
webpack-*.js 3,444 1,660 1.6 Webpack runtime
main-app-*.js 631 266 0.3 App entry (scaffold)
JS total 414,087 127,132 124.2
37d05d8*.css 1,324 592 0.6 Scaffold CSS only
HTML (SSR) 7,752 3,160 3.1 Inline RSC payload
Page subtotal 423,163 130,884 127.8 Excludes font
Inter WOFF2 (googleapis) 48,464 47.3 External font, one file
Total (incl. font) 179,348 175.1 Matches LH "155 KiB" estimate (LH uses different accounting)

1b. CRA build (local frontend/trademaster_ui/build/ — baseline)

Asset Raw (B) Gzip (B) Gzip (KiB)
main.dec84704.js 1,328,582 389,744 380.6
206.28995197.chunk.js 4,444 1,750 1.7
JS total 1,333,026 391,494 382.3
main.f362b66d.css 292,238 42,290 41.3
index.html 677 417 0.4
Total 1,625,941 434,201 424.0

1c. Delta (scaffold vs full CRA app)

Dimension Next.js scaffold CRA full app Delta
JS (gzip, KiB) 124.2 382.3 −258.1 KiB (−67.5%)
CSS (gzip, KiB) 0.6 41.3 −40.7 KiB (scaffold CSS only)
HTML (gzip, KiB) 3.1 0.4 +2.7 KiB (SSR inline RSC payload)

Interpretation: The scaffold delta is not meaningful for post-port comparison — Next.js CSS is a stub (full Bootstrap/CE styles not yet ported). JS runtime savings are real and structural: Next.js per-route code-split versus CRA single-bundle. The JS delta will compress post-port as app code is added back but routing efficiency is retained.


2. Core Web Vitals

Lighthouse 13.3.0, simulated 4G throttling, single run per route (scaffold has near-zero variance — same placeholder content on all routes except /signup). /setup redirects 307 → /login?next=%2Fsetup; metrics reflect the login page.

Route Score FCP LCP TTI TBT CLS Speed Index
/ 91 2.7 s 2.8 s 2.8 s 0 ms 0 2.7 s
/login 93 2.6 s 2.6 s 2.6 s 0 ms 0 2.8 s
/signup 96 1.6 s 2.6 s 2.6 s 0 ms 0 1.6 s
/setup (→ /login) 92 2.7 s 2.7 s 2.7 s 0 ms 0 2.8 s

Issue-level acceptance criteria (from #2881): - LCP < 2.5 s: MISS on all four routes (range 2.6–2.8 s). Delta: +100 to +300 ms over threshold. - FCP < 1.8 s: MISS on /, /login, /setup (2.6–2.7 s). PASS on /signup (1.6 s).

Root cause of FCP/LCP miss: Inter font loaded from fonts.googleapis.com with no font-display: optional or local fallback. Font discovery starts at HTML parse → CSS fetch → woff2 fetch, adding ~1.1–1.2 s to render. The font woff2 is 47.3 KiB. Fix: self-host Inter with next/font (zero render-blocking) — this is a Phase 3 port item, not a scaffold regression.

TBT = 0, CLS = 0: confirms correct — scaffold has no long tasks and no layout shift.


3. TTFB

3-trial measurements via curl, median selected.

Route Next.js staging (median TTFB) CRA raxx.app (median TTFB) Delta
/ 116 ms 56 ms +60 ms
/login 140 ms 48 ms +92 ms
/signup 183 ms 52 ms +131 ms
/setup 104 ms

Trial data:

Next.js staging:

Route Trial 1 Trial 2 Trial 3 Median
/ 111 ms 116 ms 146 ms 116 ms
/login 438 ms 140 ms 118 ms 140 ms
/signup 184 ms 117 ms 295 ms 184 ms
/setup 116 ms 91 ms 86 ms 104 ms

CRA raxx.app (CF Pages static):

Route Trial 1 Trial 2 Trial 3 Median
/ 57 ms 52 ms 152 ms 57 ms
/login 49 ms 38 ms 48 ms 49 ms
/signup 50 ms 58 ms 48 ms 50 ms

Interpretation: Next.js runs on CF Workers edge runtime (x-edge-runtime: 1 confirmed in response headers) with SSR. CRA is a static asset served from CF Pages CDN edge cache. The TTFB delta (60–131 ms) is expected: SSR invokes a Worker function per request whereas static HTML is edge-cached. This is an acceptable trade-off when SSR enables server-side auth checks (middleware.ts route guard). One /login trial spiked to 438 ms — likely a cold start; median is unaffected.

Non-US vantage: not available in this run (single vantage from LAX colo per cf-ray: a029…-LAX). Recommend adding a multi-region curl probe in Phase 3 CI (e.g. via curl-to-url GH Actions matrix with runs-on: ubuntu-latest on different runner regions, or Cloudflare Observatory API if accessible).


4. Network Waterfall (Home Page)

11 total requests on first load.

# Type Asset Transfer
1 Document staging-nextjs.raxx.app/ (SSR HTML) 3,160 B
2 Stylesheet 37d05d892a8d6825.css 1,087 B
3 Script webpack-4471baf625a7707f.js 2,156 B
4 Script fd9d1056-*.js (React runtime) 54,664 B
5 Script 30-be3f1d*.js (framework) 32,838 B
6 Script main-app-bd268aaccf88b235.js 735 B
7 Stylesheet Google Fonts CSS 1,233 B
8 Script CF RUM beacon 11,672 B
9 Font Inter woff2 48,464 B
10 XHR CF RUM ping 458 B
11 Other favicon.ico (404) 2,520 B

Critical path: HTML → CSS → JS chunks (async) → Google Fonts CSS → woff2. The font chain (items 7→9) is the render blocker driving FCP to ~2.7 s.

Largest single asset: fd9d1056-*.js at 54,664 B transferred (React runtime + router). Post-port this chunk will not grow significantly — it is framework code, not app code.

favicon.ico 404: minor — CF Pages default behavior for Workers route; fix in Phase 3 by placing favicon.ico in the public/ directory.


5. Lighthouse JSON Artifacts

Stored in docs/qa/lighthouse/ for future diff:


6. Baseline Locked

Deploy SHA: 46c57e14ci(antlers-next): Wave B Phase 1 — promote CI gates to required checks (#2937)
Build ID (Next.js): Y-F9GQODO3-2tEmeEfr72 (from RSC payload in HTML)
Repo HEAD at measurement: 773b3b50
Lighthouse version: 13.3.0
Measurement date: 2026-05-27 (UTC)
Vantage: US-West / LAX (cf-ray: a029…-LAX)


These become CI blockers at Phase 3 cutover review (not informational-only):

Metric Baseline Block if Rationale
LCP 2.8 s (scaffold) > 3.5 s on any ported route +700 ms buffer; scaffold penalized by external font; post-next/font target is <2.5 s
FCP 2.7 s (scaffold) > 3.0 s on any ported route +300 ms buffer; font self-hosting fix expected in Phase 3
First-load JS 124 KiB gz > 200 KiB gz (any single route chunk) Next.js per-route splitting; a single chunk crossing 200 KiB means a split opportunity was missed
Total byte weight 155 KiB (scaffold) > 400 KiB (any route, all assets) Headroom for full CE skin + Bootstrap; crossing 400 KiB requires explicit justification
TTFB 116–184 ms (median) > 500 ms (median of 3 trials) Cold-start outlier at 438 ms already observed; 500 ms median means systematic regression

8. Open Questions

  1. FCP/LCP target compliance post-font fix: Migrating to next/font/google with display: swap or display: optional is expected to reduce FCP to <1.8 s and LCP to <2.5 s (AC targets from #2881). This should be validated in Phase 3 before setting blockers.
  2. Multi-region TTFB: The LAX colo result does not prove global edge distribution. Add a US-East probe (GH Actions ubuntu-latest runner is typically US-East) to the Phase 3 CI workflow.
  3. CF Workers cold start: One /login trial hit 438 ms. If cold starts persist post-port with real app code, evaluate @cloudflare/next-on-pages caching strategies or Workers unbound plan for warm instances.
  4. CRA comparison completeness: CRA TTFB/Lighthouse measurements are unavailable from CF Access-gated raxx.app. The local build provides bundle sizes but no live CWV comparison. Phase 3 should measure CRA live before cutover (via a service token bypass) to get a true before/after.
  5. favicon.ico 404: Low priority but creates a wasted 2.5 KiB request + 404 error on every page load. Fix before Phase 3 cutover.