How to reduce GLB file size for the web
We shrank the models on this site by up to 99%. Here is what made the difference, with measured numbers and the commands we ran.
By the threeD editorial team. Published . 7 min read.
A 3D model that takes ten seconds to download on a phone will not be looked at. While building the sample gallery for this site we optimised 42 GLB files, and the results were consistent enough to turn into a recipe. The short version: textures are almost always the problem, and fixing them is cheap.
Measured results
Every model below went through the same single step: textures resized to at most 1024 px and re-encoded as WebP, using the open-source @gltf-transform/cli. Geometry was left untouched and no mesh compression was applied.
| Model | Before | After | Triangles |
|---|---|---|---|
| Avocado | 8.11 MB | 75.5 KB | 682 |
| Water bottle | 8.97 MB | 199 KB | 4,226 |
| Boombox | 10.6 MB | 339 KB | 5,706 |
| Lamp post | 9.56 MB | 436 KB | 4,382 |
| Corset | 13.5 MB | 889 KB | 17,606 |
| Rubber duck | 735 KB | 162 KB | 4,098 |
| Velvet lounge chair | 4.13 MB | 1.42 MB | 35,172 |
| Toy car | 5.42 MB | 2.67 MB | 80,931 |
| Treasure chest | 5.48 MB | 2.74 MB | 79,423 |
The pattern is clear. Light meshes, whose weight was mostly large textures, shrank by 75 to 99%. Models with dense geometry, like the 81k-triangle toy car and the 79k-triangle chest, only halved, because once the textures are small the remaining bytes are vertices and indices.
Step 1: find out what is heavy
Before changing anything, look at where the bytes are. The same CLI can report it:
npx @gltf-transform/cli inspect model.glbIt lists every mesh with its vertex count and every texture with its resolution and size. If the textures add up to most of the file, start there. If the meshes do, go to step 3.
Step 2: resize and re-encode textures
This one command produced every result in the table:
npx @gltf-transform/cli optimize input.glb output.glb \
--texture-compress webp --texture-size 1024 --compress false- 1024 px is plenty for a product viewer or an AR preview that fills a phone screen. Use 2048 px only for hero assets seen up close on large displays.
- WebP is supported by every current browser and by three.js, Babylon.js and model-viewer through the
EXT_texture_webpextension. Some older tools and game engines cannot read it; keep a PNG/JPEG version for those. - KTX2 / Basis textures stay compressed on the GPU, which saves video memory as well as download size. They are worth it for scenes with many models, at the cost of a slower build step and a transcoder in the viewer.
Step 3: reduce or compress geometry
If the meshes are what is heavy, there are two separate levers:
- Fewer triangles. Decimate the mesh to a budget that suits the platform. The live demo on the remesh page shows how far you can go before a silhouette breaks, and polygon budgets lists common targets.
- Compressed geometry. Draco or Meshopt compression shrinks vertex data substantially without removing triangles. Both need a decoder on the viewing side, so check your viewer supports the one you choose. We left it off for the gallery so the files open in the widest range of tools.
Step 4: check the result
Compression can go wrong quietly: a normal map that was squashed too hard, a texture that lost its alpha, a material that needed an extension your viewer lacks. Open the output in the free GLB viewer and compare it with the original in textured, clay and normals modes before you publish it.
A practical size budget
There is no official limit, but for a model embedded on a web page or opened in mobile AR, a few megabytes is a sensible ceiling, and under 1 MB loads almost instantly on a decent connection. Of the 42 gallery models, 30 are under 1 MB after optimisation and all but one are under 3 MB; the exception is a 66k-triangle boulder, where geometry rather than texture is the weight.
Need a different format after optimising? The GLB converter turns a GLB into USDZ for iPhone AR or STL for printing, entirely in the browser.