Loading video...

Video Failed to Load

Go Home

Ported Google's Draco decoder to pure JavaScript. 4.3× smaller than the WASM build, byte-for-byte identical output, often faster once you factor in load, init and parse.

95,436 views • 3 months ago •via X (Twitter)

49 Comments

mrdoob's profile picture
mrdoob3 months ago

This library shines on spotty mobile connections, where transferring 100KB takes much longer than 20KB. Even if JS parsing is slower than WASM, the model displays faster because of the reduction in network overhead.

mrdoob's profile picture
mrdoob3 months ago

Managed to reduce the bundle size. It's 5.2× smaller now.

Volodymyr Agafonkin 🇺🇦's profile picture
Volodymyr Agafonkin 🇺🇦3 months ago

Very cool! A well-optimized JS version of a code like this can match native performance in my experience too. You should try meshopt decoder next! At Mapbox, we have switched from Draco to Meshopt because it's both simpler, faster and generated smaller models for our use case.

mrdoob's profile picture
mrdoob3 months ago

Oh! I'll put that on the list 🤓

Arseny Kapoulkine's profile picture
Arseny Kapoulkine3 months ago

@mourner Pure JS version is maintained here ;) (it's not particularly optimized, I'm sure it can be faster - getting close to Wasm speed should be impossible however, and the Wasm decoder bundled into JS is pretty tiny, but just in case you need JS-only option)

Volodymyr Agafonkin 🇺🇦's profile picture
Volodymyr Agafonkin 🇺🇦3 months ago

@mrdoob Happy to see you chime in, amazing project! I guess you mean it’s impossible because of the SIMD build? But for certain cases (e.g a ton of smallish models), JS to WASM comms overhead could be bigger than the SIMD win. Worth an optimization pass attempt at least 😊

Arseny Kapoulkine's profile picture
Arseny Kapoulkine3 months ago

I would be quite skeptical; the communication overhead is really just a copy of data in & out of the Wasm heap - it's not free but it's comparatively cheap and it's easy to lose much more on inefficient codegen. It's also not just SIMD; even scalar Wasm often runs faster than optimized JS for these workloads. But of course people should experiment :)

Volodymyr Agafonkin 🇺🇦's profile picture
Volodymyr Agafonkin 🇺🇦3 months ago

@mrdoob Challenge accepted, I'm really curious! Will do some benchmarking on our typical workloads and report back

Volodymyr Agafonkin 🇺🇦's profile picture
Volodymyr Agafonkin 🇺🇦3 months ago

@mrdoob You were right! On a typical Mapbox workload (90 buffers, 16.5MB compressed total), baseline JS reference is 14x slower than WASM; after heavy optimization, it's still 3.5x slower. The WASM version is exceptionaly fast and small, and cold start is 4-5ms (negligible)

herbst's profile picture
herbst3 months ago

@fernandojsg Now do KTX2! 😄

mrdoob's profile picture
mrdoob3 months ago

@fernandojsg Tempting 😅

robot 2.0's profile picture
robot 2.03 months ago

you are really ramping up the speed lately

mrdoob's profile picture
mrdoob3 months ago

I actually did this back in January with poor Opus 4.5. Decided to do another pass with 4.8 and finish it off today.

Alex Spînu's profile picture
Alex Spînu3 months ago

This is cool - would be cool to see Cesium's gltf-pipeline for draco for batch compressing built in ( if the scope isnt to have a 1:1 draco port ) :D

mrdoob's profile picture
mrdoob3 months ago

Feel free to send a PR or do whatever it's needed 🤗

gsimone's profile picture
gsimone3 months ago

This feels like a good idea for a lot of cases, make sure to ship a benchmark - cli so agents can do it - so people can use to find the best tool for their job - eg. there's got to be a breaking point where paying the extra is worth it

David Ronai's profile picture
David Ronai3 months ago

omg thats big ! 🥳

Anderson Mancini's profile picture
Anderson Mancini3 months ago

Thats huge 🤯🤯🤯👏🏻👏🏻👏🏻

Nicola's profile picture
Nicola3 months ago

Would you recommend to use it already? I use Draco for boats models.

mrdoob's profile picture
mrdoob3 months ago

Feel free to give it a go ✌️

Aymeric Rabot's profile picture
Aymeric Rabot3 months ago

@wawasensei Yay! Thx

Gregor's profile picture
Gregor3 months ago

wasm init was costing me 380ms before a single byte parsed

Luke Wood's profile picture
Luke Wood3 months ago

This further supports my opinion that WASM is just generally not very useful.

tim's profile picture
tim3 months ago

@threejs wow

David Bang 💥's profile picture
David Bang 💥3 months ago

u r awesome

AiDevCraft's profile picture
AiDevCraft3 months ago

The "once you factor in load and init" line is the unsung headline — for one-shot mesh decodes the WASM startup tax often eats its steady-state win. Bonus is sidestepping the SharedArrayBuffer/COOP header dance the WASM build usually drags into a CDN.

Dishant's profile picture
Dishant3 months ago

the init time difference is wild. that alone makes it worth it for web use

Andrea Giammarchi 🍥's profile picture
Andrea Giammarchi 🍥3 months ago

Some crash on Safari Mobile + littlest Tokyo has no light but overall wonderful project/port

keaukraine's profile picture
keaukraine3 months ago

On my Pixel10 at battery saving power mode total improvement is ~1.1x on average. Load+init times are way longer for WASM, up to 400 ms which is user-perceivable. JS parse times are also not that bad. Overall, I agree that JS version is good enough.

Jules ⭐'s profile picture
Jules ⭐3 months ago

JS is fast 💪

just-a-programmer's profile picture
just-a-programmer3 months ago

Why is the wasm larger?

OGD's profile picture
OGD3 months ago

@threejs Sick!

Alvaro アルバロ's profile picture
Alvaro アルバロ3 months ago

@threejs 🙌

Skal's profile picture
Skal3 months ago

Oh wow, nice! You know who to ping :)

mrdoob's profile picture
mrdoob3 months ago

Haha yes. The man is very busy these days though 😅

Daniel Cluff's profile picture
Daniel Cluff3 months ago

@iced_coffee_dev This is pretty cool but it looks like parsing is often slower. This is fine for one off imports but if you are loading a large amount of assets wasm probably wins. I would like to see a benchmark that tests performance at scale.

mrdoob's profile picture
mrdoob3 months ago

@iced_coffee_dev Yeah. Do it 👌

Benny Schuetz's profile picture
Benny Schuetz3 months ago

That's pretty slick!

Carmelo schepis's profile picture
Carmelo schepis3 months ago

Impressive savings and speed boost!

hyeseong.kim's profile picture
hyeseong.kim3 months ago

Pure JS port for the real win!

🌵 Marcel Wiessler's profile picture
🌵 Marcel Wiessler3 months ago

But... in the video WASM rendering shows up before JS - what am I missing?

Erik Sombroek's profile picture
Erik Sombroek3 months ago

Thats really nice!

Palash Bansal's profile picture
Palash Bansal3 months ago

This is awesome, will put it in the 3d model quicklook app

Guilherme O'Tina's profile picture
Guilherme O'Tina3 months ago

this is a great counterexample to the assumption that wasm is always the right call for web delivery. for long-running compute wasm wins easily. but for draco decoding where each call is short and the init overhead dominates, pure JS can win on total time plus bundle. 4.3x smaller changes the economics for shipping 3d on the web

Jens Fursund's profile picture
Jens Fursund3 months ago

This is awesome!

Afshawn Lotfi's profile picture
Afshawn Lotfi3 months ago

used to use Draco, like meshoptimizer better

tandavas's profile picture
tandavas3 months ago

@iced_coffee_dev Extremely cool!

Saad Haider's profile picture
Saad Haider3 months ago

Parse time is always bigger so for a game with alot of models, .js wont matter as the total parse time would make it par with the .wasm

mrdoob's profile picture
mrdoob3 months ago

Yes

Related Videos