Version
1.59.1
Steps to reproduce
- Build any wasm module with a hot numeric kernel, e.g. with emscripten:
// bench.c: float math + memory writes over a 4 MB buffer
#include <emscripten/emscripten.h>
#define BUF_FLOATS (1 << 20)
static float g_buf[BUF_FLOATS];
EMSCRIPTEN_KEEPALIVE float bench_raster(int iters) {
float acc = 0.0f;
for (int it = 0; it < iters; ++it)
for (int i = 0; i < BUF_FLOATS; ++i) {
g_buf[i] = g_buf[i] * 0.75f + (float)i * 0.25f;
acc += g_buf[i];
}
return acc;
}
emcc -O2 bench.c -o bench.js -sMODULARIZE -sEXPORT_ES6
-
Load it in a page that times the kernel repeatedly (20+ calls so the optimizing tier has every opportunity to kick in) and report per-call wall time.
-
Run that page in Playwright Firefox (browserType: firefox) and in a stock Firefox release on the same machine.
Expected behavior
Warm calls speed up as SpiderMonkey tiers the module up to the optimizing compiler, matching stock Firefox within normal noise.
Actual behavior
In Playwright's bundled Firefox the module appears to stay on the baseline wasm tier indefinitely:
- Warm per-call time equals cold per-call time; no tier-up ever happens no matter how long the kernel runs.
- Hot numeric kernels run 14-18x slower than stock Firefox (153, same machine, same wasm binary).
- Setting the wasm tiering prefs via
firefoxUserPrefs (javascript.options.wasm_optimizingjit and related) has no observable effect, while the same prefs change behavior in stock Firefox.
The practical consequence: any performance measurement of a wasm-heavy app under Playwright Firefox is invalid. We chased a "Firefox is 3.5-4x slower than Chromium" result in our app's frame benchmarks for days before isolating it to the bundled build; stock Firefox is at parity with Chromium on the same page (UI frame p50 8.6 ms vs 8.6 ms), while Playwright Firefox reports 3.7-4x.
If the optimizing tier is intentionally disabled in the bundled build, a note in the docs (and ideally a way to opt back in) would save users from silently invalid perf numbers.
System info
- macOS 15 arm64 (Apple Silicon)
- @playwright/test 1.59.1, bundled Firefox
- Comparison browser: stock Firefox 153 release, same machine, same wasm binary
I have a fuller microbenchmark harness (engine-generic kernels, indirect-call-dense variant, cold/warm tables) and can attach it on request.
Version
1.59.1
Steps to reproduce
emcc -O2 bench.c -o bench.js -sMODULARIZE -sEXPORT_ES6Load it in a page that times the kernel repeatedly (20+ calls so the optimizing tier has every opportunity to kick in) and report per-call wall time.
Run that page in Playwright Firefox (
browserType: firefox) and in a stock Firefox release on the same machine.Expected behavior
Warm calls speed up as SpiderMonkey tiers the module up to the optimizing compiler, matching stock Firefox within normal noise.
Actual behavior
In Playwright's bundled Firefox the module appears to stay on the baseline wasm tier indefinitely:
firefoxUserPrefs(javascript.options.wasm_optimizingjitand related) has no observable effect, while the same prefs change behavior in stock Firefox.The practical consequence: any performance measurement of a wasm-heavy app under Playwright Firefox is invalid. We chased a "Firefox is 3.5-4x slower than Chromium" result in our app's frame benchmarks for days before isolating it to the bundled build; stock Firefox is at parity with Chromium on the same page (UI frame p50 8.6 ms vs 8.6 ms), while Playwright Firefox reports 3.7-4x.
If the optimizing tier is intentionally disabled in the bundled build, a note in the docs (and ideally a way to opt back in) would save users from silently invalid perf numbers.
System info
I have a fuller microbenchmark harness (engine-generic kernels, indirect-call-dense variant, cold/warm tables) and can attach it on request.