Building this website with Remix 3 — A walkthrough of how this portfolio is constructed — from the clientEntry component model to the WebGL particle background and the glassmorphic landing UI.
building-this-website-with-remix [Remix, Architecture, WebGL]
When I set out to rebuild my personal site, I wanted something that felt alive without sacrificing performance. The result is a glassmorphic landing page backed by a lightweight WebGL particle field and a component model that ships almost no JavaScript to the client.
Every interactive piece is a clientEntry. The server renders the markup, and only the bits that actually need behavior get hydrated. The Page component is just a function that returns a render function:
export function HomePage(handle: Handle<HomePageProps>) {
return () => (
<Document title={HOME_TITLE} stylesheets={[styleHrefs.portfolio]}>
<Header />
<main>{/* ... */}</main>
<Footer />
</Document>
);
}This keeps the mental model simple: data flows in, a tree of Remix elements comes out. There is no virtual DOM diffing ceremony to reason about.
The starfield is a single WebGL canvas. The trick to keeping scroll smooth is throttling the draw loop to ~30fps and pausing entirely when the tab is hidden:
function frame(now: number) {
if (document.hidden) {
// resume on visibilitychange, don't spin
return;
}
if (now - lastDraw >= FRAME_INTERVAL) {
lastDraw = now;
drawBatch(S, skyLightColors, skyLightAlphas);
}
raf = requestAnimationFrame(frame);
}Performance is a feature. A beautiful background that janks on scroll is worse than no background at all.
— Me
That's the core of it. The rest is just good typography, restraint with color, and respecting prefers-reduced-motion.