3D on the web in 2026: when WebGL earns its cost and when it tanks LCP
Every agency portfolio has a 3D landing page. Half of them convert. The other half render at 12 fps on mid-range Android and lose visitors before the hero finishes fading in. Here is the decision framework we use before adding WebGL to a client site.

TL;DR3D on the web is a conversion tool when it renders under 200 ms and holds 60 fps on mid-range Android. It's a conversion killer when it doesn't. Rules that separate the two: (1) never in the LCP element; (2) mobile budget is 60 fps at 5W thermal, not desktop at 30W; (3) if you can't ship it as a screenshot with the same emotional impact, you probably shouldn't ship it at all.
Every agency portfolio has a 3D landing page. Half of them convert. The other half render at 12 fps on mid-range Android and lose visitors before the hero finishes fading in.
Here is the decision framework we use at Praxvon before adding WebGL to a client site — and the specific mobile-first techniques that make it work when we do.
The three questions
1. Does the 3D communicate something a video or a still can't?
If the interaction is decorative — a slowly rotating logo, a parallax-drifting field of particles — you're paying a heavy budget for a screenshot with a wobble. Ship the screenshot instead. It'll load faster, work on every device, and communicate the same thing.
WebGL earns its cost when the 3D is the product: a product configurator where you rotate the model, a data visualization where the camera path tells the story, an interactive brand piece where the interaction is the emotional payload.
2. Can you hold 60 fps on a $200 Android phone?
The mistake: test on the developer's MacBook and ship. Result: the site runs at 60 fps for you, at 12 fps for the majority of visitors.
The rule we apply: the 3D scene has to hold 60 fps on a mid-range Android (Snapdragon 6-series, ~3-year-old device) in low-power mode. If it doesn't, budget-cut until it does — reduce polycount, drop post-processing effects, disable shadows, simplify shaders — or ship a CSS-only fallback that mobile users see.
3. Is the 3D scene above the LCP threshold?
Google measures LCP against the largest visible element. If the 3D canvas is that element, LCP is bounded by WebGL initialization time (typically 400–800 ms even with a fast bundle). You've capped your Core Web Vitals at "Good" and given up "Excellent" before the first frame renders.
The rule: WebGL is never the LCP element. Static image or CSS text hero, WebGL scene enters after LCP fires.
Techniques that make it work
Lazy-init the WebGL context after LCP. Load Three.js dynamically. The main bundle stays lean. The scene bootstraps only after the browser reports LCP has completed. Total bundle cost of Three.js + R3F + drei: ~140 KB gzipped. Not shipping that on the critical path is a Core Web Vitals win worth having.
Detect + fallback aggressively.
window.devicePixelRatio > 1 && matchMedia('(pointer: coarse)').matches
is a decent heuristic for "mid-range mobile". If detected, either drop
to a low-quality fallback (fewer particles, smaller texture atlases) or
skip the scene entirely and show a static hero.
Reduce polycount + texture size ruthlessly. Most agency 3D scenes ship with 500k+ polygons where 50k would look identical at the render resolution. Blender's Decimate modifier is your friend. Textures rarely need >1024×1024; usually 512 is fine at browser render density.
Composite shadows in the texture, not the shader. Real-time shadow mapping is expensive. Baking shadows into the texture gives 90% of the visual effect at 0% of the runtime cost. Loses subtly if the camera moves in ways that expose the fixed shadow angle, but usually acceptable.
Skip post-processing entirely on mobile. Bloom, chromatic aberration, motion blur — all easy to add, all expensive per frame. On mobile, cut them. Desktop keeps them.
Frameworks
- Three.js: the incumbent. Best documentation, largest ecosystem, most examples on Stack Overflow.
- React Three Fiber: React binding for Three.js. Recommended if
the rest of the site is React.
dreiprovides ergonomic components (Environment, useGLTF, PerspectiveCamera) that would otherwise be boilerplate. - PlayCanvas / Babylon.js: alternatives worth considering for game-shaped interactivity. Overkill for most brand work.
We default to React Three Fiber for client work because the ergonomics compose well with the rest of a Next.js app.
When we ship 3D
- Product visualization where the user should rotate + inspect. Selling physical products or complex interactive UIs.
- Data visualization where the camera path tells a story.
- Brand hero where the interaction is the emotional payload (rare).
- Interactive maps / building floorplans where the third dimension is genuinely spatial.
When we don't
- Rotating logo, drifting particles, glowing gradient. Ship a video or a static.
- Portfolio hero of an agency that already ranks well on Google — don't bet Core Web Vitals on decoration.
- Any e-commerce product page where LCP directly affects revenue. Every 100 ms of LCP costs measurable conversion.
The praxvon.com scene-based experience
The praxvon.com /experience route is scene-based (wheel + keyboard
navigation between 5 full-viewport scenes). It's not the LCP element —
/ serves a proper SSR marketing page. The scene experience is a
separate route users opt into.
That split matters. Our home page is Google-indexable content. The scene experience is a portfolio piece for users who want to explore. Search engines get the flat marketing story; visitors who want the emotional piece get it, but don't gate everyone else on it.
Working on a site where 3D might earn conversion, or trying to figure out whether to keep a scene you already have? Contact us — we've seen both sides of this and can give an honest read on whether the WebGL is paying for itself.