Closed pastelmind closed 2 years ago
One of our long-term goals has been using WebAssembly to improve image decoding performance. We initially implemented an asm.js decoder to explore possible performance gains. While we did see a reasonable improvement, we cannot continue to use asm.js for the following reasons:
These problems meant that we must adopt WebAssembly at some point; that is now.
The following is a detailed explanation of this pull request. It's long, so hold tight.
Note: This pull request depends on #19.
Vite is a modern build tool. It supports TypeScript and native ESM better than Webpack, and does not require as many plugins to work. It's also very fast for development builds.
Vitest is a test framework which integrates well with Vite, and handles native ESM better than Jest.
We rewrote the asm.js decoder in Rust. This is compiled to WebAssembly using wasm-pack. The WASM binary is bundled into the build artifact (dist/index.js
) as a base64-encoded string. This means that users can continue to use whatever build tool they were using w/o fear of breaking the library. The downside is that the bundle is considerably larger (~73 KiB), but this shouldn't be a problem if your server uses HTTP compression.
When the library is imported, the WASM binary is decoded asynchronously, then the rest of the module is initialized. @webtoon/psd now exports a Promise
named init
, which resolves when the initialization is done. Users must ensure that the promise is resolved before accessing other values exported by @webtoon/psd--this includes the default export, too!
import PSD, {init} from '@webtoon/psd';
PSD.parse(/* ... */); // error, the library has not been initialized yet
(async () => {
await init; // Wait for the library to initialize itself
// Note that 'init' is NOT a function!
// await init() <-- this is invalid
PSD.parse(/* ... */);
})();
// If you can use top-level await, this becomes considerably simpler
await init;
PSD.parse(/* ... */);
// Since 'init' is added to the task queue when the library is imported,
// it should probably be loaded by the time an event handler fires.
// Thus, this should _probably_ be safe.
elem.addEventListener('someEvent', () => {
PSD.parse(/* ... */);
})
From now on, developers must install wasm-pack on their system to build @webtoon/psd.
Preliminary testing indicates that the new WASM decoder performs comparably to the old decoder. In the future, we hope to gain further performance improvements.
For the full story, see the second comment.
Summary of changes
For users
Await theNot needed once #24 is mergedinit
promise before using @webtoon/psd:For developers
rpm install
-ing this project will also install wasm-pack.