[PHP] Recompile PHP.wasm ASYNCIFY with MAIN_MODULE set to 2#3335
[PHP] Recompile PHP.wasm ASYNCIFY with MAIN_MODULE set to 2#3335brandonpayton merged 6 commits intotrunkfrom
MAIN_MODULE set to 2#3335Conversation
MAIN_MODULE set to 2
|
@brandonpayton Well, not as light as Node builds but, still :
Now the entire PHP.wasm builds are dead code eliminated. 🎉 Size Reduction
Per-version
|
| PHP Version | Before (avg) | After (avg) | Reduction |
|---|---|---|---|
| 7.4 | ~20 MB | ~17 MB | 17–19% |
| 8.0 | ~21 MB | ~17 MB | 17–19% |
| 8.1 | ~24 MB | ~20 MB | 15–17% |
| 8.2 | ~25 MB | ~21 MB | 15–17% |
| 8.3 | ~25 MB | ~21 MB | 15–17% |
| 8.4 | ~27 MB | ~23 MB | 14–16% |
| 8.5 | ~28 MB | ~24 MB | 14–15% |
Web vs Node Build Comparison
| Platform | Before | After | Saved | Reduction |
|---|---|---|---|---|
| Node builds | 468.8 MB | 402.2 MB | 66.6 MB | 14.2% |
| Web builds | 419.4 MB | 364.0 MB | 55.4 MB | 13.2% |
Breakdown by file type
| Platform | .wasm saved |
JS glue saved | .so delta |
|---|---|---|---|
| Node builds | 59.4 MB (16.5%) | 8.0 MB (62.4%) | +0.7 MB |
| Web builds | 49.6 MB (15.4%) | 6.5 MB (65.4%) | +0.7 MB |
The slight
.soincrease (~0.7 MB per platform) is due to the rebuilt Intl extension now including additional symbols needed forMAIN_MODULE=2compatibility.
Breakdown by variant
| Build | Before | After | Saved | Reduction |
|---|---|---|---|---|
| Node Asyncify | 241.6 MB | 208.4 MB | 33.2 MB | 13.7% |
| Node JSPI | 227.2 MB | 193.8 MB | 33.4 MB | 14.7% |
| Web Asyncify | 219.1 MB | 191.7 MB | 27.4 MB | 12.5% |
| Web JSPI | 200.3 MB | 172.4 MB | 28.0 MB | 13.9% |
JS glue code reduction
| Build | Before | After | Saved | Reduction |
|---|---|---|---|---|
| Node Asyncify | ~957 KB | ~360 KB | ~597 KB | 62% |
| Node JSPI | ~912 KB | ~340 KB | ~572 KB | 63% |
| Web Asyncify | ~735 KB | ~263 KB | ~472 KB | 64% |
| Web JSPI | ~716 KB | ~236 KB | ~480 KB | 67% |
Line Changes
| PR | JS Glue Lines Before | JS Glue Lines After | Net |
|---|---|---|---|
| #3332 (JSPI) | 422,100 | 146,463 | -275,637 |
| #3335 (Asyncify) | 439,850 | 160,694 | -279,156 |
| Combined | 861,950 | 307,157 | -554,793 |
Performance Implications
MAIN_MODULE=2 tells Emscripten to only export symbols actually needed for dynamic linking, rather than exporting everything. This yields:
- Smaller download size — 122 MB less across all builds means faster CI, faster clones, and faster deployments
- Faster WebAssembly instantiation — Smaller
.wasmfiles take less time to compile and instantiate in the browser (compilation cost is roughly proportional to binary size) - Lower memory usage — Fewer exported symbols means a smaller function table and less memory overhead at runtime
- Smaller JS glue code — 63% smaller JS files means faster parsing and less memory for the JavaScript engine
It would be interesting to benchmark the runtime impact, particularly WebAssembly instantiation time, time-to-first-PHP-response, and memory usage, to quantify the performance gains beyond file size.
This is great, @mho22! Thank you! |



Motivation for the change, related issues
Following-up on : #3332
This pull request sets
MAIN_MODULE=2to PHP.wasm Node Asyncify and PHP.wasm Web Asyncify.Implementation details
Updated the
php/Dockerfilescript to enableMAIN_MODULE=2by default.Ran the following commands
Now the entire PHP.wasm builds are dead code eliminated. 🎉
Size Reduction
.wasmfilesPer-version
.wasmreductionWeb vs Node Build Comparison
Breakdown by file type
.wasmsaved.sodeltaBreakdown by variant
JS glue code reduction
Line Changes
Performance Implications
MAIN_MODULE=2tells Emscripten to only export symbols actually needed for dynamic linking, rather than exporting everything. This yields:.wasmfiles take less time to compile and instantiate in the browser (compilation cost is roughly proportional to binary size)Testing Instructions (or ideally a Blueprint)
CI