How zeriotic.com Renders
Architecture
- Vite + Vanilla JS (no framework overhead)
- Three.js for the WebGL particle field + chrome sculpture
- GSAP + ScrollTrigger for scroll-driven storytelling
- Lenis for smooth scrolling
- Netlify for hosting + serverless functions
[ CDN / Edge ] => [ Static HTML / CSS ]
|
+-- [ Vite JS Bundle ]
|
+-- [ Main Thread ] --> Scroll & Layout (Lenis/GSAP)
|
+-- [ WebGL Thread ] --> Particle Field (Three.js)
Key Engineering Decisions
1. On-Demand Rendering
The GPU only renders when something changes (scroll, tween, resize). Static sections release the GPU entirely. This means battery life on laptops and silent fans.
2. Dynamic Resolution Scaling
A closed-loop scaler driven by real GPU timer queries (EXT_disjoint_timer_query_webgl2). It holds the highest resolution the GPU can sustain, stepping down only when frames exceed budget. No guessing from rAF deltas.
3. SMAA ←” FXAA Motion Swap
During camera movement, expensive SMAA is swapped for cheap FXAA (motion masks the quality difference). When movement stops, SMAA renders one crisp frame.
4. Particle Field Architecture
120K particles in a single draw call. Position morphing via vertex shader (no CPU buffer updates during animation). MeshSurfaceSampler distributes points on Blender sculptures.
5. Adaptive Quality Tiers
GPU name detection, core count, device memory → three tiers (high/medium/low) controlling particle count, pixel ratio, and post-processing.
Performance Numbers
- 3 GLB models: 55 KB total
- 120K particles: single draw call, vertex-shader animated
- Median TTFB: 12ms (Netlify CDN)
- First meaningful paint: under 2 seconds
- GPU state: idle when reading solid content sections