DEV Community

Divyakush Punjabi
Divyakush Punjabi

Posted on

Keeping a graphics-heavy React app at a smooth 60fps

A 3D visualization that stutters doesn't just look bad — it actively teaches the wrong thing. If your sorting animation hitches, a learner reads the hitch as part of the algorithm. So on a graphics-heavy educational app, 60fps isn't polish. It's correctness.

Hitting it consistently was the real engineering challenge in AlgoVerse, and the fix is a pattern worth stealing for any interactive app.

The trap: computation and rendering fighting for the frame

The naive way to animate an algorithm is to interleave "compute the next step" with "draw the current state" in the same loop. You get one of two failure modes: the animation freezes while the algorithm thinks, or the algorithm races ahead faster than the eye can follow. Either way, the frame budget is being spent on the wrong thing at the wrong time.

Real-time 3D makes this worse, because Three.js rendering already competes hard for that budget. Add unbounded computation on the same thread and you drop frames exactly when the scene is busiest — which is exactly when the learner is watching.

The split that fixes it

The architecture separates the two concerns completely:

  • The algorithm produces a stream of discrete steps — a comparison, a swap, a rotation — as data, not as draw calls.
  • The renderer plays those steps back at a controllable rate, on its own schedule, decoupled from how fast the algorithm generated them.

That separation is what makes the speed slider (0.25×–4×) possible at all, and it's what keeps a 200-element sort or a large graph from freezing the UI. The computation can finish in a blink; the playback is what the human sees, and playback is smooth by construction.

The discipline underneath

The broader lesson generalizes far past visualizations: be deliberate about what re-renders and when. In React, that means keeping the visualization state predictable (TypeScript throughout helped), isolating the pieces that animate from the pieces that don't, and never letting a heavy computation block the paint.

Any interactive app — a dashboard, an editor, a game — lives or dies on this. The moment your compute and your render share a thread and a schedule, you're one big input away from jank.

AlgoVerse made me treat 60fps as a hard requirement rather than a nice-to-have, and the render/compute split is the single decision that made it achievable. The full build is on the project page.

👉 See it run: www.divyakush.com/projects/algoverse


Divyakush Punjabi — Full-Stack & AI Systems Engineer

🌐 https://www.divyakush.com · 💼 LinkedIn · 💻 GitHub

Top comments (0)