demo · v147
Trace upload
Worker A runs a real CPU-heavy load. A second worker profiles it with the JS Self-Profiling API at a chosen sample rate, aggregates the trace into a hot-functions list off the main thread, and emits a compact payload ready for navigator.sendBeacon.
Behind a flag: JS Self-Profiling in dedicated workers ships behind the Document
Policy
js-profiling, gated by chrome://flags/#enable-experimental-web-platform-features
in Chrome 147. This page is served with the required policy header and reports unavailable browsers instead of fabricating traces.
samples collected
—
distinct functions
—
trace size (raw)
—
payload size (aggregated)
—
| function | samples |
|---|---|
| no profile yet | |
Aggregated payload (what we'd send to a telemetry endpoint)
no payload yet
pipeline idle
What's happening
- Worker A spins up a
Workerthat runs naïvefib(28), a heap-allocatingJSON.parse, and an array sort. - Worker A wraps the load in
new self.Profiler({ sampleInterval }), calls.stop(), posts the raw trace. - Main thread hands the raw trace to Worker B, which aggregates by leaf function — the "process traces in a worker" pattern from the WICG explainer.
- The compact payload is shown above. The button calls
navigator.sendBeacon('/telemetry/profile', payload)for real.
// inside worker A (Chrome 147, Document-Policy: js-profiling)
const profiler = new self.Profiler({ sampleInterval: 10, maxBufferSize: 10000 });
doExpensiveWork();
const trace = await profiler.stop();
self.postMessage({ kind: 'trace', trace });
// main thread → worker B
workerB.postMessage({ kind: 'aggregate', trace });
see also
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗