Merse.
BlogPlate 45
Engineering

What real-time 3D actually costs on a marketing site

A 3D scene that drops frames is worse than no scene. Here is the budget we hold a WebGL marketing page to — what we spend it on, what we refuse to, and the four decisions that do most of the work.

Plate
45
Subject
Engineering
Issued
01 Sept 2026

Most 3D on the web is a demo that escaped. It looks extraordinary on the machine it was built on, and it stutters on the phone of the person you actually wanted to impress. The scene is not the problem. The problem is that it was loaded like any other asset, on the same thread that was trying to scroll.

So before any of the interesting work — lighting, material, camera — we set a budget. It is not a target we hope to hit at the end. It is the constraint the scene is designed inside from the first commit.

The budget

Four numbers, held on a mid-range Android over a throttled connection, not on a laptop over office wifi:

  • The 3D contributes nothing to Largest Contentful Paint. LCP is text or an image that ships in the initial HTML. If the canvas is the LCP element, the page is built wrong.
  • No frame over 50ms during scroll — including the frames where the scene is initialising. This is the one everybody misses: the jank is not in the render loop, it is in the setup.
  • The renderer and the model are zero bytes until the reader has shown intent. The page ships without them and picks them up later.
  • The scene degrades rather than disappears. Every device gets something; only the fidelity moves.

Where the cost actually is

It is tempting to treat the model file as the expense, because it is the number you can see. It is usually not. A meshopt-compressed GLB is often smaller than the hero video on the same page. The expensive moments are the ones with no file size at all: environment map pre-filtering, shader compilation, texture upload to the GPU, and the first frame the decoder produces.

Each of those is a synchronous block on the main thread. Land one during a scroll and the reader feels it, no matter how light the model was.

A janky scene is worse than no scene. It does not read as ambitious. It reads as broken.

Gate at the arrival end, not the kickoff

The common fix is to wrap the dynamic import in requestIdleCallback and call it done. That gates almost nothing. The import starts when the browser is idle, but it resolves whenever the network decides — and the expensive continuation runs the instant it lands, which on a cold CDN is very likely to be mid-scroll.

The gate has to sit at the far end. Let the bytes arrive whenever they arrive, then wait for a genuine settle in the scroll before doing the work: build the scene, warm one texture per idle beat, compile the shaders asynchronously, and only then reveal. On our own case study this moved the worst frame on a throttled CPU from 167ms to 67ms, with the scene rendering pixel-for-pixel identically.

Cap the pixels before you cap the polygons

Fragment cost scales with the number of pixels shaded, and a modern phone will happily report a device pixel ratio of three. Rendering a full-bleed canvas at 3× is nine times the fragment work of 1×, for a difference most readers cannot see on a moving object.

Capping the ratio — and choosing that cap from device memory rather than screen width — is usually a bigger win than any mesh decimation, and it costs nothing in authored quality. Decimate only after the pixel budget is set.

Decide the fallback first

The scene should not be the only way to understand the page. Write the section so it works with a still frame, then add the real-time version on top for the devices that can hold it. That ordering matters: a page designed around a canvas has nothing to say when the canvas cannot run, and a crawler — which executes no WebGL at all — sees an empty box.

When not to ship a scene

If the 3D does not carry information — if it is a shape rotating because rotating shapes look expensive — the budget is better spent on the page being faster and the copy being clearer. Real-time 3D earns its cost when the subject is spatial and a photograph genuinely cannot show it: a building you want to walk around, a product you want to open, a process you want to watch assemble.

That is the test we apply before anything gets modelled. Everything above is only worth doing once the scene has passed it.

Questions this raises

Does 3D slow down a website?
It can, badly — but only if it loads like a normal asset. The cost is not the 3D itself; it is loading a renderer, a model, and shader compilation on the same thread that is trying to scroll. Gate all of it behind idle time and intent, and the page stays as fast as it was before the scene existed.
Will a 3D website hurt my Core Web Vitals?
Not if the scene is excluded from the critical path. LCP should be text or an image that ships in the initial HTML, never the canvas. If the 3D chunk is loaded after first paint and after the browser reports idle, it does not contribute to LCP, and a capped device pixel ratio keeps it out of INP.
Do 3D websites work on phones?
Yes, but they should not be the same scene. Phones have a fraction of the GPU budget and are usually on a worse network. We ship the same page with a lighter scene, a lower pixel ratio, or a static poster frame, decided from device memory and screen size rather than a user-agent guess.
Is 3D worth it for a B2B or real-estate site?
It is worth it where the thing being sold is spatial or physical and a photograph cannot show it — a building, a product, a process. It is not worth it as decoration. If the scene does not carry information the page would otherwise need paragraphs to explain, the budget is better spent elsewhere.