Building 3D Web Experiences That Do Not Wreck Performance
WebGL can make a site unforgettable or unusable. The difference comes down to a handful of decisions about draw calls, device tiers and knowing when to switch the whole thing off.
Three.js makes it trivially easy to put something spectacular on a landing page and trivially easy to melt a mid-range Android phone doing it. Both outcomes come from the same few lines of code. Here is the discipline we apply to every WebGL build we ship.
Budget draw calls before you budget polygons
Modern GPUs eat triangles happily. What they dislike is being interrupted. A scene with two hundred separate meshes at a thousand triangles each will consistently underperform one merged mesh with two hundred thousand triangles. Instanced meshes and merged geometry are the first optimisation, not the last.
Tier your devices honestly
We classify visitors into three tiers on first paint — using device memory, hardware concurrency and a quick renderer probe — and scale particle counts, pixel ratio and post-processing to match. A flagship desktop gets the full scene. A budget phone gets a simplified version at a capped pixel ratio. Nobody gets a slideshow.
const tier = navigator.deviceMemory <= 4 || navigator.hardwareConcurrency <= 4
? 'low'
: window.devicePixelRatio > 2 ? 'high' : 'mid';
renderer.setPixelRatio(Math.min(window.devicePixelRatio, tier === 'low' ? 1 : 2));Stop rendering when nobody is looking
The single largest battery win available is also the easiest: pause the render loop when the canvas scrolls out of view or the tab loses focus. An IntersectionObserver and a visibilitychange listener take about ten lines and routinely cut idle GPU usage to nothing.
Respect reduced motion
prefers-reduced-motion is not a suggestion. For users who set it, we hold the scene still and render a single composed frame. The page still looks designed; it simply stops moving. Vestibular disorders are common enough that ignoring this excludes real customers.
The content has to survive without it
Our rule is that every WebGL layer is decoration over a page that already works. If the context fails to initialise, if the GPU is blocklisted, if a corporate proxy strips the bundle — the headline, the copy and the call to action are all still there, styled with CSS. Spectacle is the upside, never the dependency.
Tagged
Working on something like this?
We are happy to talk through a technical decision even when it does not turn into a project. NovaGen is based in Minuwangoda, Sri Lanka and works with clients worldwide.