Skip to content
Back to work

Personal project · 2023 — Present

Portfolio experiments lab

Where interaction ideas get tested before they reach client work

  • Next.js
  • React Three Fiber
  • three.js
  • Motion
  • Canvas 2D
  • TypeScript

The problem

Interaction ideas are cheap to describe and expensive to discover halfway through a client build. I needed somewhere to find out what a technique actually costs — in frame budget, in bundle size, in accessibility debt — before proposing it to anyone paying for it.

The approach

This site is the lab. A React Three Fiber scene with GLTF models, a full-viewport Canvas 2D glitch effect, pointer-tracked glow surfaces and scroll-linked timelines all exist here first, which is how I learned which of them survive contact with a mid-range phone and which do not.

The outcome

A working set of judgements rather than opinions: which effects are worth their cost, which need capability gating, and which need to be switched off entirely when someone has asked for reduced motion. The refresh documented in docs/portfolio-refresh-audit.md is the result of turning that lens on my own code.

Architecture moves

  • React Three Fiber scenes loaded as lazy client islands via next/dynamic, kept out of the initial bundle.
  • Motion tokens centralised in lib/motion so durations, easings and springs are shared values rather than magic numbers.
  • Capability and reduced-motion gating handled at the provider level, so individual components do not each reimplement the check.
  • Canvas effects driven by a single requestAnimationFrame loop rather than per-component intervals.

Performance levers

  • Heavy 3D and canvas work is dynamically imported, so the first paint does not wait for it.
  • Animation restricted to transform and opacity wherever the effect allows.
  • Scroll and pointer listeners throttled and passive, and the number of simultaneously animating elements capped on small screens.
  • Effects disabled outright on touch and low-power devices instead of merely slowed down.

Engineering impact

  • Turned a portfolio into a test bed, which makes the technique choices in client work evidence-based.
  • Produced the reusable motion and gating primitives this site now runs on.
  • Gave me a documented audit of my own animation defects — including the ones I had shipped.

Challenges conquered

  • Wanting a cinematic feel while keeping first paint fast, which is mostly a fight about what is allowed to block rendering.
  • Making reduced motion a genuine alternative rather than the same animation played slowly.
  • Accepting that some effects I liked were not worth their cost on a mid-range Android.