From a 4 GB CAD Assembly to a 1.9 MB Web Page: What Actually Shrinks a 3D Product Model
A field note on asset budgets for interactive 3D product configurators. The problem On a recent delivery, the engineering team handed us a 4 GB STEP assembly. The product page had to render an interactive, co
A field note on asset budgets for interactive 3D product configurators.
The problem
On a recent delivery, the engineering team handed us a 4 GB STEP assembly. The product page had to render an interactive, configurable model on a normal mobile connection, with the first frame on screen before the rest of the page felt blocked. Our working budget for the first frame was 2 MB. We shipped at 1.9 MB.
That gap is not closed by "enabling compression". It is closed by a specific sequence of decisions, and doing them in the wrong order wastes most of the effort. Here is what we learned, in the order we actually run it.
Where the weight really comes from
Before touching any codec, measure the assembly. In our experience the bulk sits in five places:
- Triangle count from CAD tessellation. CAD surfaces are exported with a tolerance meant for manufacturing, not for a screen. A single fillet can produce thousands of triangles nobody will ever see.
- Internal and hidden geometry. Bolts, brackets, cavities and back faces that are never visible in any allowed view.
- Materials and textures. Duplicated materials, uncompressed PNG textures, and 4K maps on parts that occupy 40 px on screen.
- Uninstanced duplicates. Twenty identical screws exported as twenty separate meshes instead of one mesh with twenty transforms.
- Node and metadata overhead. Deep scene graphs, unused cameras, PMI and embedded metadata carried straight through the exporter.
The first three usually account for well over 90% of the file. Compression alone cannot fix geometry that should not be there.
The order that works
- Decimate and retopologise first. Reduce triangle count against a target silhouette error, not a fixed percentage. Check the silhouette at the smallest viewport you support.
- Delete non-visible geometry. Anything that cannot appear in an allowed camera or configuration state goes. This is a modelling decision, not a compression setting.
- Merge materials and compress textures. Combine identical materials, move to KTX2 / Basis Universal for GPU-native formats, and size each map to its real on-screen footprint.
- Instance repeated parts. One mesh, many transforms. This is often the single largest win on assemblies with hardware.
- Apply geometry compression last. Only now do Draco or Meshopt make sense — you are compressing geometry that has already earned its place.
- Split only if the budget still fails. More on that below.
Draco vs Meshopt
Both are mature and both will cut a GLB substantially, but they optimise for different things.
| Draco | Meshopt | |
|---|---|---|
| Strength | Smallest payload when bandwidth is the bottleneck | Fastest decode, lower CPU cost at runtime |
| Typical use | Static hero model, slow networks | Configurators with frequent variant swaps |
| Decode | Relatively expensive on low-end mobile | Cheap, often noticeably faster to first frame |
| Tooling | Widely supported in glTF pipelines | Strong support in Three.js / glTF-Transform |
For a configurator that swaps finishes and options on every click, decode cost compounds. We generally prefer Meshopt there and reserve Draco for a static single-model page where bytes are the dominant constraint. Measure on a real mid-range phone; desktop numbers are misleading.
When to split instead of compress
There is a point where further compression deforms the product. The better move is to split the model into a small first-frame shell plus on-demand chunks:
- Load the shell (silhouette + primary surfaces) within the 2 MB budget.
- Defer optional components, interiors and high-detail variants until the user interacts.
- Reuse the same geometry across variants rather than exporting a full model per option.
This also improves perceived performance: the page becomes interactive before everything has arrived, and Core Web Vitals stay intact because the heavy payload is off the critical path.
Pre-ship checklist
- [ ] Silhouette checked at the smallest supported viewport after decimation
- [ ] No internal or never-visible geometry left in the scene
- [ ] Textures in KTX2 / Basis, sized to real on-screen pixels
- [ ] Repeated parts instanced
- [ ] No IP-sensitive metadata or PMI carried into the public GLB
- [ ] First-frame budget measured on a throttled mobile connection
- [ ] Variant swaps tested without re-downloading the base mesh
- [ ] Largest Contentful Paint measured with the 3D view enabled
Takeaway
A 4 GB CAD file is not a web problem, it is a pipeline problem. Retopologise, delete, merge, instance, then compress — and split when the budget still will not hold. The codec is the last step, not the first.
We are Took3D, a Web3D studio building interactive 3D product configurators for manufacturers and retailers. Longer field notes on the CAD-to-web pipeline and on choosing between a 360 spin and a full configurator:
- https://www.took3d.com/company-news/reduce-glb-file-size-for-web.html
- https://www.took3d.com/company-news/how-to-prepare-cad-files-for-a-web-3d-configurator.html
- https://www.took3d.com/company-news/360-spin-vs-3d-configurator.html
Questions about a specific assembly or platform are welcome in the comments.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.