wasm (de)compression - is this really working, or am I getting it wrong?

Godot Version

4.3

Question

I am testing the waters in browser games, and it’s all working pretty great in 4.3 beta. I’ve managed to get the size of the exported .wasm down to about 20MB by building my own custom export template, with everything disabled I could think of.

Now I was wondering if I could compress the .wasm. My very basic understanding is that decompression is transparently done by the browser, if the web server provides content-type / content-encoding correctly. So Godot shouldn’t have anything to do with it, really.

My naive approach is thus:

  • Manually compress the index.wasm file to index.wasm.br
  • Replace all references to ‘.wasm’ in index.html and index.js by ‘.wasm.br’
  • Upload the whole thing to the server
  • See what happens

In my case, I’m uploading to crazygames.com, and: this seems to work! I’ve reduced my .wasm to ~4MB, and the game loads fine. Even to my phone.

Am I overlooking something? I’m a total noob when it comes to web stuff, so I can’t really believe that this is the right way to do it. I hardly even know what I’m talking about.

Please someone enlighten me.

Thanks!

2 Likes

Nice! I am surprised it works that way, i would’ve expected index.html/js to require a uncompressed blob.

I would bet if the server supports compression then you would not have to do this manually. gzip compression for instance is totally transparent, the server sends less bytes to the client by a gzip file, the client immediately decompresses it. Not sure if it would show as saving bandwidth if you aren’t profiling it within your web browser/network tab.

I am just as surprised!

In this case, the server doesn‘t handle compression transparently. The download time directly reflects the size of the files I upload. The difference is mindblowing - the wasm went from 40mb using the vanilla web export template, to 20mb using my own, to 4mb compressed - a mere 10%!

1 Like

It’s strange that this works, as this means the web server is using the right Content-Encoding: br header for the compressed files but is not automatically redirecting index.wasm to index.wasm.br if the latter exists.

I’m curious if this works on itch.io and GitHub Pages. Also try this for the PCK file, which can benefit a lot from compression depending on its contents.

1 Like

Hm, that kind of automatic redirection sounds great, but it doesn’t seem to be in place anywhere?

Here are some quick test results:

crazygames.com, itch.io, github.io all failed to load the page with the original index.js / index.html and my manually compressed index.wasm.br:

index.js:15549
GET https://prod-dpgames.crazygames.com/standalone/0691de41-7810-499e-9afc-40273977fa78/Ascent-Export-Web/index.wasm 403 (Forbidden)

index.js:15549
GET https://html.itch.zone/html/10920566/Ascent-Export-Web/index.wasm 403 (Forbidden)

index.js:15549
GET https://scruffyowl.github.io/index.wasm 404 (Not Found)

With the modified index.js / index.html (requesting index.wasm.br), the page loads on crazygames.com, and itch.io

On github.io, this didn’lt load either:

index.js:150 Uncaught (in promise) CompileError: WebAssembly.instantiateStreaming(): expected magic word 00 61 73 6d, found 8f ff 3f 00 @+0
at index.js:150:17

I’m guessing the github.io server doesn’t set the content-encoding, so the data isn’t transparently decompressed?

I’ve tried to use .gz with with GitHub, too, but that failed in both scenarios. I’m not familiar with github pages, so I might have messed up something in setting up the test…

About the PCK file, how would this work? Wouldn’t the server have to be explicitly configured for .pck and .pck.br suffixes? I don’t think this is a widely used extension?

You can serve any file type with precompression, as long as the web server sends the correct file. Alternatively, like you did for index.html, you modify index.js to download the compressed PCK file URL (while ensuring it has the correct Content-Encoding: br header).

Ah, ok. So the server would send a brotli content-encoding for any *.br file requested by the client, and the browser can then transparently decompress it and pass the result to the loader code? Sorry if these are dumb questions, I am trying to understand how this web stuff works :slight_smile:

1 Like

Yes, that should work although it’s been a while since I tested (around Godot 3.4).

2 Likes

I know this is an old thread so sorry for the question, but how did you compress your .wasm file to .br?

If you are on linux you would use brotli index.wasm, though as mentioned web browsers/servers usually take care of automatic compression when sending and recieving files, so you may only reduce compatibility.

1 Like