- Problem
- The landing was to get a 3D hero, but its mobile LCP element was the lead paragraph and the page already shipped about 182 KB of JS.
- Choice
- I built one test scene four ways on spike pages (React Three Fiber, plain three.js, Spline, a video loop) and measured each. I shipped plain three.js behind a one-time gate (reduced motion, Save-Data, WebGL2 without a major performance caveat, no software renderer, 4+ cores and 4+ GB) over a server-rendered poster in a fixed frame.
- Why
- Plain three.js drew the same scene for 187 KB gzip against 247 KB for R3F and 602 KB for Spline, with a first frame 2 to 4 times faster. LCP and CLS did not move, because nothing 3D loads before the gate.
- Trade-off
- I own the lifecycle by hand (resize, dispose, context loss, FPS guard, about 150 lines). A review later found the canvas leaking across page changes until I created it outside the React tree.