Using WebAssembly for a NodeJS Native Addon
FUJI Goro Nov 17, 2017 Updated on Nov 18, 2017
I have a story for this package: it is built with Emscripten into WebAssembly.
WebAssembly is a portable executable format for the web browsers, but it is not only for the web but usable for nodejs native addons. That is, the package includes pre-built executable binary in wasm. No compiler is required to install it. No node-pre-gyp magic is required (in fact node-zopfli has problems with node-pre-gyp pierreinglebert/node-zopfli#87). Even Windows users can use it just by
npm install @gfx/zofpli (or
yarnpkg add @gfx/zopfli).
You might be worried about wasm performance, but I think it is already production-ready, although it is slower than native code.
Here is a benchmark result in the repo on NodejS 8.9.1 (see benchmark/random-bytes.js for the code):
payload size: 1
universal-zopfli x 106 ops/sec ±0.79% (80 runs sampled)
node-zopfli x 201 ops/sec ±1.99% (82 runs sampled)
payload size: 1024
universal-zopfli x 1.37 ops/sec ±12.99% (11 runs sampled)
node-zopfli x 4.62 ops/sec ±3.34% (27 runs sampled)
payload size: 1038336
universal-zopfli x 0.26 ops/sec ±6.91% (6 runs sampled)
node-zopfli x 0.39 ops/sec ±1.35% (6 runs sampled)
The speed (ops/sec) of universal-zopfli (i.e. in wasm) is about 30% - 70% of node-zopfli (i.e. in native code). It is good enough for production if you use
@gfx/zopfli as a Zlib alternative in compression-webpack-plugin. And fortunately, the current state of WebAssembly implementation in NodeJS/V8 is just an MVP! It should be getting better in performance.
Development of nodejs native addon with Emscripten is difficult for now, but I believe most of NodeJS native addons which do not use systemcalls, including nodejs standard libraries such as zlib, can be replaced with wasm because of its portability.