feat: add WASM runtime probe to detect slow WebAssembly#20
Conversation
# Conflicts: # src/web-capabilities.spec.ts # src/web-capabilities.ts
bbaldino
left a comment
There was a problem hiding this comment.
lgtm to me overall. am i understanding correctly that it runs the operation in js and in wasm and then compares the ratio of their elapsed times to evaluate if wasm appears to be sufficiently faster? either way, i think a comment somewhere describing that approach would be useful--probably on a public method since the approach seems relevant to the API, I'm sure others will wonder as well (or I might've missed it somewhere).
Thank you for checking it @bbaldino! You are right, this is the best way to find out if a user has issues running effects for us. We have a few different edge cases to handle. Sometimes there is no WASM at all, and other times we hit the Edge issue where WASM is available but super slow because the JIT policy forces it off. This causes major issues in calls using BNR and VBG. Because of this, benchmarking the speed for both JS and WASM is the most stable method. The JIT policy causes them to be very slow, so their timing ratio is the key here. If they run at almost the same ratio, we can be confident the browser is capable of running effects. I will definitely update the API👌thank you for the feedback! Just for reference, here is the link to the specific issue we were trying to fix with this change: https://confluence-eng-gpk2.cisco.com/conf/spaces/webexmedia/pages/872747588/Edge+JIT+Policy+Breaks+Webex+BNR#EdgeJITPolicyBreaksWebexBNR-how-to-fix-it |
Description
Follow-up to #19 (
supportsWasm()). That check tells us WebAssembly exists and this onetells us whether it runs fast enough.
Some browsers ship WebAssembly but run it through a slow interpreter instead of the JIT
(e.g. Edge with JIT off, or locked-down enterprise policies). WASM is "present", so
supportsWasm()saysCAPABLE, but it's too slow for real-time effects like BNR andVBG. This probe catches that so we can gate those features on measured performance, not
just feature detection.
How it works: it times the same tight loop in WASM vs JS off the main thread and looks at
the
wasmMs / jsMsratio — comparing the two normalizes for the user's CPU (a real JITkeeps WASM at least as fast as JS; an interpreter loses badly). Notable choices:
Every edge path (no WASM, no Worker, worker error, timeout) resolves to a safe
UNKNOWNinstead of throwing.
Changes
src/wasm-runtime-probe.ts—WasmRuntimeProbeclass +WasmJitStatus(
OK/SLOW/DISABLED/UNKNOWN) andWasmRuntimeResultsrc/wasm-runtime-probe.worker.js— the worker: builds the in-memory WASM module andreports the median of several runs so a one-off hiccup doesn't skew things.
src/web-capabilities.ts— newsupportsWorker()check;src/index.tsexports the probe.rollup-plugin-string+jest.raw-transform.jsinline*.worker.jsas astring (tests swap in a fake Worker, so the worker code never runs under test).
cspell.json— dictionary additions.Consumer
@webex/plugin-meetings will calls
WasmRuntimeProbe.check()to decide whether to enableBNR / VBG, giving users on interpreter-only WASM a graceful fallback.
This change implements...
Is this a breaking change?
I certify that...
Generative AI (GAI) Usage Disclosure
Reference: Cisco GAI Coding Guidelines
If a GAI tool/IDE was used then select the category that best describes GAI usage in this PR: