A 47 MB GLB Shrinks to 8 MB Without Touching a Terminal
1. The Pain Point First
Anyone doing Web3D has probably been through this: the art team happily delivers a GLB, you drop it into the page — and bam, 47 MB. The first screen stays white for 8 seconds, users curse and close the page, and the boss asks you "why do other people's models load so fast."
What's worse, many projects have data confidentiality requirements: military, medical, industrial manufacturing — the model simply cannot be uploaded to any third-party online tool. You search the entire internet, and all the compression tutorials you find are command-line based, or web tools that require uploading files — an instant dealbreaker.
I recently took on a product landing page project, and I've organized the whole trial-and-error process and final solution here, hoping it saves you some detours.
2. First, Understand: Where Exactly Is the GLB So Big?
Don't rush to compress before diagnosing. A GLB's size basically consists of three parts:
- Geometry data (vertices, indices, normals)
- Texture maps (baseColor, normal, roughness, etc. — often the biggest chunk)
- Animation / node structure
The rule of thumb is simple: if textures dominate, prioritize texture compression; if geometry dominates, prioritize mesh compression. My 47 MB model this time was a classic "geometry + texture both high" case, so both sides needed treatment.
3. Mesh Compression: Draco vs Meshopt — Which One to Pick?
These are the two mainstream options you can't avoid for GLB compression, both official glTF extensions. The differences are as follows:
| Comparison Item | Draco (KHR_draco_mesh_compression) | Meshopt (EXT_meshopt_compression) |
|---|---|---|
| Compression Ratio | High (geometry data -70~90%) | Higher (integrated geometry + scene graph optimization) |
| Decode Speed | Fast | 5~10x faster (WebGPU-friendly) |
| Texture Compression | JPEG / WebP / KTX2 | BasisU (ETC1S / UASTC) built-in |
| Framework Support | Three.js / Babylon.js / model-viewer | Three.js r136+ |
| Suitable Scenarios | Broad compatibility, Babylon.js projects | New projects, performance-focused |
My experience: For new projects chasing loading performance, prefer Meshopt; for projects using Babylon.js or model-viewer, stick with Draco (these two frameworks don't support Meshopt).
But here's the problem — the command line is a huge turnoff. Every time I compressed before, I had to dig through docs to piece together parameters: one line for Draco, one for Meshopt, another for textures, and after compression I'd have to write my own script to compare sizes — extremely inefficient.
4. My Solution: A GUI Compression Tool That Runs Offline
Later I found Zipoly — a desktop model compression tool that runs completely offline, and the key point is: no command line, files never leave your machine. For confidential projects it's a necessity; for ordinary projects it's genuinely hassle-free.
4.1 Getting Started Is Simple
The download address is on the official site: zipoly.netlify.app. The installer is tiny (around 5 MB), ready to use after installation, no internet needed the whole time. The interface is clean, with four functions in the left nav: Compression Optimization, Format Conversion, 3D Viewer, Operation Logs.
4.2 Three Steps for Compression
Step 1: Import the model, read the health report
Drag the 47 MB GLB in, and the software automatically runs a health check, telling me directly:
- Vertex count, triangle count, texture count, animation count
- Potential issues (duplicate vertices, oversized textures, missing normals, etc.)
- Recommended compression level
This step is crucial — before, I had to open several tools to gather all this info; now it's all there on import.
Step 2: Choose the engine, directly follow its recommendation
My new project this time uses Three.js, so I picked the "Web 3D Scene" preset (Meshopt engine) based on its scenario suggestion. If your project uses Babylon.js, just pick the "Industrial Visualization" preset (Draco engine). No hesitation — it also has built-in automatic fallback: if Meshopt is unavailable it automatically falls back to Draco, the result is unaffected.
The default compression level is 7, generally a good starting point:
| Level | Suitable Scenario |
|---|---|
| 1~3 | Engineering / Medical / Precision models, accuracy first |
| 4~6 | Product showcase, architectural visualization |
| 7 (default) | General Web3D, recommended starting point |
| 8~9 | Mobile, low bandwidth, acceptable slight distortion |
| 10 | Background decoration, noticeable geometric distortion |
Step 3: Click "Start Optimization", wait for the comparison result
The compression process shows real-time progress across three stages: "Geometry Compression → Texture Optimization → Writing File". My 47 MB model finished in about a minute, and the comparison window that popped up read: 47 MB → 8 MB, size reduced by 83%.
I strongly recommend clicking "Preview Effect" after compression to see the model's appearance with your own eyes in the built-in 3D viewer — whether the quantization parameters are right, your eyes are the best judge; don't just look at the numbers.
4.3 Why I Use It Long-Term
After using it for a while, three points impress me most:
- Offline operation, safe for confidential projects. Model files never leave your machine — military, medical, corporate intranet scenarios are fully covered, no anxiety about uploading files to someone else's server.
- Automatic health check + visual comparison. Problem areas are flagged directly, and you can preview before compression — no guessing.
- Batch compression. Select a folder once, recursively scan all GLB/glTF, with pause/resume/cancel support — a blessing for asset pipeline work.
Oh, and if you only have FBX/OBJ/STL/DAE/PLY on hand, its built-in "Format Conversion" can directly interconvert 7 formats, and you can compress right after conversion — a one-stop shop.
5. How to Load After Compression? Copy This Three.js Code Directly
Compression is only the first step; the loading side must also be configured with the decoder, otherwise you'll get errors. The complete Three.js code is as follows:
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';
const loader = new GLTFLoader();
// 1. If Draco compression was used, configure Draco decoder (recommend local deployment; accessing Google CDN from China is unstable)
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/'); // copy three/examples/jsm/libs/draco to your public folder
loader.setDRACOLoader(dracoLoader);
// 2. If Meshopt compression was used, configure Meshopt decoder
loader.setMeshoptDecoder(MeshoptDecoder);
// 3. If textures were compressed to KTX2, also configure KTX2Loader
// const ktx2Loader = new KTX2Loader();
// ktx2Loader.setTranscoderPath('...basis/');
// ktx2Loader.detectSupport(renderer);
// loader.setKTX2Loader(ktx2Loader);
// 4. Load normally
loader.load(
'/models/building.glb',
(gltf) => { scene.add(gltf.scene); },
(xhr) => { console.log(`${(xhr.loaded / xhr.total * 100).toFixed(1)}%`); },
(err) => { console.error('Load failed:', err); }
);
If using Babylon.js or model-viewer, just load directly, no extra configuration needed — but these two frameworks don't support Meshopt, so remember to choose the Draco engine when compressing.
6. A Few Easy Pitfalls
- Forgetting to configure the decoder after compression. A Draco-compressed GLB loaded without
DRACOLoaderwill error; same for Meshopt. - Don't force compression on small models. Models with < 1000 faces or < 100 KB in size — the compression metadata overhead outweighs the benefit; the result might even be larger.
- Model deformed or jagged after compression? Lower the compression level (7→5), don't push through.
- Always preview after compression. Whether the quantization parameters are right, your eyes are the most honest — don't skip this step.
7. Summary
A huge GLB isn't a dead end. The core is one sentence: Draco/Meshopt for geometry, KTX2/WebP for textures, and configure the decoder after compression. 90% of model size problems can be solved.
On the tool side, my advice is: go offline if you can, don't upload; go visual if you can, don't guess. Zipoly is free to download, and Mac/Linux users also have an install-free web online version; small files can freeload too. The official site is here: zipoly.netlify.app, grab it if you need it. Not an ad — I'm sharing because I genuinely find it useful.
If you have a model that just won't compress, welcome to post your data in the comments and let's talk.