Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat][CLI]: add w4 opt | wasm-opt integration #261

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

FaberVitale
Copy link
Contributor

@FaberVitale FaberVitale commented Dec 29, 2021

Description

This PR adds w4 opt that is a simple opinionated integration of wasm-opt provided by binaryen.js.

Usage

$ node cli/cli.js opt --help
Usage: w4 opt|optimize [options] <cart>

optimize and minimize cart size using binaryen wasm-opt

Options:
  -o, --output <file>  output wasm file (default: "./cart-opt.wasm")
  -s, --silent         do not print to stdout (default: false)
  -h, --help           display help for command

wasm-opt flags

'-Oz',
'--strip-dwarf',
'--strip-producers',
'--zero-filled-memory',

New Dependencies

This PR adds binaryen.js as dependency of "wasm4".

Tested node versions

  • node v14.18.0 (npm v6.14.15)
  • node v16.4.2 (npm v7.18.1)

Feedback

Ideas and improvements are welcome.

@netlify
Copy link

netlify bot commented Dec 29, 2021

✔️ Deploy Preview for wasm4 ready!

🔨 Explore the source changes: 5898224

🔍 Inspect the deploy log: https://app.netlify.com/sites/wasm4/deploys/61ccadb63811e500078c3a9a

😎 Browse the preview: https://deploy-preview-261--wasm4.netlify.app

@joshgoebel
Copy link
Contributor

This happens automatically at compile time if someone has wasm-opt installed... is it too much to expect someone to modify their build settings if they wanted to add an extra setting? I think the built-in support already does everything but `'--strip-dwarf'?

If that's too hard is there a reason not to make that easier - rather than making optimization a separate step?

@aduros
Copy link
Owner

aduros commented Dec 30, 2021

Is bundling native binaries of wasm-opt a possibility? The JS/wasm version of wasm-opt has a noticeably slow startup delay for me.

@christopher-kleine
Copy link
Contributor

Not all languages provide a way to opt the cart.wasm.

  • AssemblyScript: Built into the compiler
  • C/C++, Go, Nelua: Part of the Makefile
  • D, Odin: Could be provided in the Makefile (currently, it's not)
  • Nim: Part of the cart.nimble
  • Rust: Not part of the Build-System (hence BIG files by default)
  • Zig: AFAIK Not part of the Build-System

This is also one of the reasons why I opened #203
I think we need one way to build and optimise stuff.

@FaberVitale
Copy link
Contributor Author

FaberVitale commented Dec 30, 2021

if they wanted to add an extra setting?
#261 (comment)

I'd like to have an opinionated version that works without much configuration or knowledge of the underlying tool.
I wonder If it would make sense to provide a w4 wasm-opt subcommand that simply calls wasm-opt.

Note that you can already use wasm-opt even if you do not have it installed using npx:

npx --package=binaryen -- wasm-opt --help

The JS/wasm version of wasm-opt has a noticeably slow startup delay for me.
#261 (comment)

The slow startup is caused by npx that resolves binaryen remotely before spawning the wasm-opt process.
I can call it directly using node bin:
that should remove the intial lag.

Is bundling native binaries of wasm-opt a possibility?
#261 (comment)

Yes but it is harder to maintain and you need to either:

  1. Use a post-build hook and those are frowned upon and might not be run by the package manager.
  2. Host on wasm4 repo the binaries or add binaryen as a git submodule (aka build from source inside the pipelines).

Note that binaryen binaries are not tiny: https://github.com/WebAssembly/binaryen/releases/tag/version_104

wasm-pack installs wasm-opt from
GH releases page but a similar approach is more problematic because you might end up having write permission issues.


This is also one of the reasons why I opened #203
I think we need one way to build and optimise stuff.
#261 (comment)

👍

I think that we should also add readme files to every starting template:
e.g. create-next-app-template

@aduros
Copy link
Owner

aduros commented Jan 4, 2022

The startup delay I mentioned happens in the JS/wasm version even when invoking without npx:

$ time node_modules/binaryen/bin/wasm-opt --version
wasm-opt version 104 (version_104)
node_modules/binaryen/bin/wasm-opt --version  10.18s user 0.20s system 349% cpu 2.969 total
$ time ./binaryen-version_104/bin/wasm-opt --version
wasm-opt version 104 (version_104)
./binaryen-version_104/bin/wasm-opt --version  0.00s user 0.00s system 83% cpu 0.004 total

3 second delay for the JS version vs basically instant for the native version.

@FaberVitale
Copy link
Contributor Author

The startup delay I mentioned happens in the JS/wasm version even when invoking without npx:

$ time node_modules/binaryen/bin/wasm-opt --version
wasm-opt version 104 (version_104)
node_modules/binaryen/bin/wasm-opt --version  10.18s user 0.20s system 349% cpu 2.969 total
$ time ./binaryen-version_104/bin/wasm-opt --version
wasm-opt version 104 (version_104)
./binaryen-version_104/bin/wasm-opt --version  0.00s user 0.00s system 83% cpu 0.004 total

3 second delay for the JS version vs basically instant for the native version.

That's quite a bit.
This is what I get.

time cli/node_modules/.bin/wasm-opt  --version 
wasm-opt version 104 (version_104)

real    0m1.566s
user    0m5.594s
sys     0m0.228s

Alternatives to binaryen.js

If we are not going to use binaryen.js I see 4 possible alternatives:

  1. Load all versions of binaryen or just wasm-opt inside wasm4 package:
    wasm-opt (mac) is just 892KB but wasm-opt.exe is 5.4MB, a bit too much in my opinion.

  2. Download wasm-opt at postinstall.

I'm not a big fan of this solution because downloading executables at postinstall is a bit sketchy and could not work if the users installs wasm4 with the flag ignore-scripts.

Note that there's already a package that uses this approach: https://www.npmjs.com/package/wasm-opt but I've not tried it.

  1. Use optional dependencies. This is the primary approach used by esbuild and falls back to postinstall if user installs it using --no-optional.

  2. Lazy approach, download binaryen the first time a user calls w4 opt.


I personally prefer solution 3. or 4.

I believe that this feature is important and should be part of wasm4 but I'm open to feedback regarding implementation details.

@joshgoebel
Copy link
Contributor

Could it be "both" is perhaps an option...? ...if it's much easier to package the nodejs version then perhaps it could be used and users just deal with how slow it is and a tiny message says "this could be much faster if you install binaryem, purely optional"...

I mean technically you'd want to/need to use this for release, not necessarily every single build, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants