Skip to content

Add optimize_wasm build option for Web #105388

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

adamscott
Copy link
Member

Note

This PR is the second of two (maybe more to come?) that intends to apply some optimizations underlined by @popcar2 in his great blog post on How to Minify Godot's Build Size (93MB -> 6.4MB exe).

Warning

Heads-up release management team: This is an independent PR from #105371, but I would prefer the latter being merged first as there will be conflicts.

This PR adds the optimize_wasm build option for the Web platform. This will permit people to optimize the built wasm files from the Godot build script, without having to manually do it. It requires though the wasm-opt command line utility from the binaryen project.

Hopefully, this will enable smaller engine downloads for players on the Web.

@adamscott adamscott added this to the 4.5 milestone Apr 14, 2025
@adamscott adamscott requested a review from a team April 14, 2025 15:47
@adamscott adamscott requested a review from a team as a code owner April 14, 2025 15:47
@adamscott adamscott force-pushed the add-binaryen-wasm-opt branch 2 times, most recently from e48fae8 to 9d5acb9 Compare April 14, 2025 15:51
@adamscott adamscott force-pushed the add-binaryen-wasm-opt branch from 9d5acb9 to 51c018d Compare April 14, 2025 15:52
@MewPurPur
Copy link
Contributor

What's the relationship between this PR, #97457, and #97407?

@@ -57,6 +58,11 @@ def get_opts():
"Use Emscripten PROXY_TO_PTHREAD option to run the main application code to a separate thread",
False,
),
BoolVariable(
"optimize_wasm",
"Use binaryen `wasm-opt` to reduce the output .wasm file sizes",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Use binaryen `wasm-opt` to reduce the output .wasm file sizes",
"Use Binaryen `wasm-opt` to reduce the output WebAsssembly file sizes (requires `wasm-opt` in `PATH`)",

def run_optimize_wasm(target, source, env):
wasmopt_bin_path = WhereIs("wasm-opt")
if wasmopt_bin_path is None:
raise UserError('[wasm-opt] Cannot find `wasm-opt`. That binary usually comes with the "binaryen" package.')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise UserError('[wasm-opt] Cannot find `wasm-opt`. That binary usually comes with the "binaryen" package.')
raise UserError('[wasm-opt] Cannot find `wasm-opt` in `PATH`. That binary usually comes with the "binaryen" package.')

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally (rebased on top of master 6a6a116), it mostly works as expected.

One issue is that the new file does not replace the existing WASM file in bin/. Instead, it creates a new file with the name godot.web.template_release.wasm32.opt.wasm (notice .opt which is normally not here). It should replace the existing WASM file so that you don't need to change anything else to your packaging process.

Also, Emscripten's copy of wasm-opt (which is in emsdk/upstream/bin/wasm-opt) is already automatically called when you compile a web export template. Is there a way to use more aggressive arguments out of the box when using optimize=speed|size|size_extra, so we don't need to run it twice? Reusing Emscripten's copy of wasm-opt would also remove the need for the user to supply their own copy of wasm-opt. See also #97457 (comment).

Benchmark

Web release export template:

Type Uncompressed gzip -9 brotli --best zstd --ultra -22
wasm_opt=no 37,477,863 bytes 9,116,302 bytes 6,228,636 bytes 6,677,737 bytes
wasm_opt=yes 34,207,409 bytes 8,909,506 bytes 6,231,975 bytes 6,684,047 bytes

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

Successfully merging this pull request may close these issues.

3 participants