WebNN vs WebGPU for Browser AI
Compare matched model outputs across operator coverage, warm-up, latency tails, memory, fallback, portability, and output parity.
WebNN vs WebGPU is meaningful only for a named model, runtime version, browser build, and device cohort—not as a universal browser AI benchmark. This comparison holds the model and inputs constant while measuring operator coverage, warm-up, latency tails, memory, fallback, and output parity.
WebNN vs WebGPU begins with one model receipt
Freeze the model URL and hash, opset, tensor shapes, preprocessing, postprocessing, precision, input corpus, runtime version, browser version, operating system, and device identifiers. WebNN vs WebGPU results without those fields cannot be reproduced because a runtime may partition operators differently across releases. Record whether measurements include model download, graph compilation, shader pipeline creation, and first execution.
Choose a modest production candidate rather than a showcase network: perhaps a small image classifier or embedding model that fits the target phones and laptops. Browser AI inference succeeds when the complete interaction meets a product budget, not when one kernel wins a synthetic race. The vision token budget guide offers a related lesson: workload shape and user outcome should constrain the technology, not the other way around.
Publish the input corpus or a redistributable substitute with expected outputs. A backend benchmark that depends on private examples cannot be independently checked and makes later runtime regressions unnecessarily difficult to isolate.
Add a server execution control if privacy and connectivity policy allow it. The comparison may show that local acceleration is not yet the best path for the selected model and cohort.
| Evidence | WebNN | WebGPU | Fallback |
|---|---|---|---|
| Operator coverage | Graph-dependent | Runtime kernels | Wasm/CPU |
| Warm-up | Compile | Pipelines | Initialize |
| Tail latency | Measure | Measure | Measure |
| Device loss | Rebuild | Recreate | Stay useful |
| Parity | Tolerance | Tolerance | Reference |
- Graph: same model and tensors
- WebNN: implementation-selected acceleration
- WebGPU: runtime-provided compute kernels
- Reference: bounded CPU parity oracle
Qualify availability by the build you tested
The WebNN specification defines a graph API intended to map neural-network operations to available device acceleration. The specification is not a browser-support table. State exactly which browser version, flag state, operating system, and device exposed the WebNN API during the run, then feature-detect at runtime. Never turn one successful lab device into “WebNN is supported in browsers.”
The same discipline applies to WebGPU machine learning. WebGPU provides portable GPU access, but adapter capabilities, limits, precision behavior, and driver quality vary. WebNN vs WebGPU documentation should separate standards capability, runtime implementation, and tested deployment evidence. A product fallback must remain visible when either API is absent, initialization fails, or a required operator cannot run on the selected backend.
Date every capability table and link it to a probe result. Readers can then distinguish a historical lab observation from current standards text and know exactly which row needs rerunning after a browser update.
Automate feature probes without turning them into browser fingerprints. Report only the capability categories needed for routing and aggregate analytics at a level that cannot single out unusual devices.
Probe operator coverage before timing anything
Load the graph and capture which operators, data types, shapes, and fusions each path accepts. A backend that supports 95 percent of operators but transfers tensors to CPU around the remaining five percent may lose both latency and memory. If the runtime partitions graphs, record every boundary and transfer. WebNN vs WebGPU should compare complete graph execution, not only the favorable accelerated subgraph.
ONNX Runtime Web documents browser execution providers and is a practical integration reference, but pin the exact package and provider configuration used. Treat ONNX Runtime Web as a runtime layer, not as proof that every model maps identically. Validate conversion outputs and unsupported-operator errors in CI, and retain a known-small fixture that exercises the operators your product actually depends on.
Capture the final partition plan when the runtime exposes it, or infer boundaries from supported diagnostics without overclaiming. A silent CPU fallback may preserve correctness while invalidating the latency and power story that motivated acceleration.
Fail model loading before user work begins when required operators are unsupported. Partial initialization followed by a late opaque error wastes bandwidth and makes fallback feel like data loss.
Measure first useful result and steady state
Users experience download, cache, initialization, compilation, first inference, and only then repeated inference. Report cold first-use and warm-cache sessions separately. For each, measure median, p95, and p99 latency across enough iterations to expose compilation spikes and thermal throttling. WebNN vs WebGPU may reverse depending on whether the product runs one inference after a click or hundreds in a camera loop.
Record peak JavaScript heap where available, estimated tensor and GPU allocations, model bytes, cache bytes, and process termination. Avoid claims of exact device memory when the API cannot expose it; describe the measurement proxy. Keep UI responsiveness beside inference timing, because a slightly faster backend that monopolizes resources can still make browser AI inference feel worse than a bounded CPU fallback.
Run repeated sessions long enough to observe thermal and cache effects, then cool or randomize treatments fairly. Alternating backends on one hot device without a protocol can make the second candidate look worse for reasons unrelated to its execution model.
Measure energy with a documented proxy when direct power readings are unavailable. Battery drop, task-manager samples, and thermal behavior are imperfect, so label them as comparative observations rather than hardware facts.
This dependency-free cohort probe compares normalized evidence rather than pretending to benchmark unavailable APIs inside Node; it makes the selection rule and abstain state executable.
Runnable artifact — browser-backend-selector.test.mjs
import assert from "node:assert/strict";
const choose=rows=>{const eligible=rows.filter(x=>x.available&&x.coverage===1&&x.parity<=x.tolerance&&x.p95<=x.budget&&x.fallback);if(!eligible.length)return"collect-more";return eligible.sort((a,b)=>a.p95-b.p95||a.warmup-b.warmup)[0].name};
const cohort=[{name:"webnn",available:true,coverage:1,parity:.0008,tolerance:.001,p95:34,budget:50,warmup:120,fallback:true},{name:"webgpu",available:true,coverage:1,parity:.0005,tolerance:.001,p95:42,budget:50,warmup:88,fallback:true}];
assert.equal(choose(cohort),"webnn");assert.equal(choose(cohort.map(x=>({...x,coverage:.92}))),"collect-more");assert.equal(choose([{...cohort[0],parity:.02}]),"collect-more");console.log("PASS: backend selection requires coverage, parity, tails, and fallback");
Run node browser-backend-selector.test.mjs. Expected receipt: PASS: backend selection requires coverage, parity, tails, and fallback.
Prove output parity with task-aware tolerances
Bitwise equality is often unrealistic across numerical backends, while a loose cosine threshold can hide meaningful class flips or boundary changes. Compare raw tensors with declared absolute and relative tolerances, then compare product outputs: top-k labels, embedding neighbors, bounding boxes, or generated control decisions. Store the worst mismatches and their inputs. A WebNN vs WebGPU winner must remain inside a tolerance justified by user-visible behavior.
Use a CPU or server reference for a small canonical corpus and include adversarial numeric cases such as zeros, extremes, padding boundaries, and dynamic shapes. If lower precision is enabled, identify it as a separate treatment. Never tune the tolerance after seeing a candidate mismatch without adding a reason and regression example, because that converts parity validation into an approval ritual.
Inspect downstream decisions near thresholds. A numerically tiny embedding change may reorder two neighbors or cross a safety boundary, while a larger internal tensor difference may leave the visible result unchanged.
Store parity failures as small tensor fixtures when licensing permits. They become valuable cross-backend regression cases and help runtime maintainers reproduce a discrepancy without obtaining the full private corpus.
- 1Detect
Record tested API and device capability
- 2Load
Prove complete operator coverage
- 3Measure
Compare cold, warm, tails, memory, and UI
- 4Recover
Test fallback, device loss, and output parity
Design fallback as a first-class product state
Feature detection is only the first branch. Initialization can fail, an adapter can disappear, device loss can occur, or memory pressure can terminate the process. Preserve a smaller Wasm or server route, a reduced model, or a clear unsupported state before enabling the accelerated path. Minimal WebGPU surfaces explains how reducing exposed capability can improve recovery and review.
Fallback parity includes UX, not just tensors. Maintain focus, progress, cancellation, privacy disclosure, and a useful static result when acceleration is unavailable. WebNN vs WebGPU should not create a blank screen for unsupported devices. Log selected path and coarse device cohort with privacy-preserving labels, then watch fallback rate and failure category rather than collecting a fingerprint-like hardware inventory.
Test recovery after WebGPU device loss and after the page returns from suspension. Preserve user input and either rebuild safely or route to fallback, rather than asking the person to reconstruct their task.
Make the fallback choice reversible within one session. A device-loss or memory failure should switch paths at a safe boundary and preserve the original input, consent, and cancellation state.
Compare maintenance and portability costs
WebNN delegates more graph mapping to the implementation; WebGPU commonly relies on a runtime's kernel library and shader pipelines. That difference changes bundle size, debugging surfaces, model-conversion work, and who owns performance regressions. Include runtime upgrades, browser releases, driver bugs, model changes, and accessibility review in the decision table. A fast prototype is not automatically the cheaper two-year system.
The comparison resembles WebGPU vs Canvas for generative art: preserve the composition—or here, the model—while exposing lifecycle costs. If WebNN wins only on a narrow tested cohort, route just that cohort and keep evidence for the rest. If WebGPU wins because a mature runtime covers your graph today, write that version-bound fact instead of declaring one API categorically superior.
Assign an owner to runtime upgrades and model conversion. An unowned accelerated path quickly becomes a frozen dependency whose apparent speed advantage blocks security, browser, or model updates.
Count engineering time spent on kernels, conversion, debugging, and compatibility during the prototype. Those hours are measured evidence for ownership cost, not an embarrassment to omit from a performance chart.
Publish a cohort-specific backend decision
Summarize the named model, tested dates and versions, cohort coverage, operator mapping, cold and warm distributions, memory proxies, parity tolerance, fallback success, and ownership. The honest verdict can be conditional: choose WebNN on supported Windows devices, WebGPU on the tested macOS cohort, and Wasm elsewhere. WebNN vs WebGPU becomes useful when routing policy matches measured evidence instead of a single global feature flag.
Re-run the probe when a browser, runtime, model, or device mix materially changes. Keep a Wasm Components tool boundary in mind if model preprocessing or fallback logic needs portable isolation. Browser acceleration is volatile by design; the durable engineering asset is the matched corpus and decision receipt that can be replayed as implementations improve.
Show the routing rule in product diagnostics without exposing fingerprinting detail. Support teams need to know which backend answered and why fallback occurred, while users deserve a stable experience regardless of the selected path.
Avoid changing backend routing during an in-progress comparison or user task. Stable session assignment keeps output and latency evidence interpretable, while new sessions can adopt a newly validated rule.