v147 · JavaScript · Workers · Performance

Compatibility Lab

Detects the JS Self-Profiling API (Profiler) both on the main thread and inside a Worker. Runs a live new Profiler() call in a worker context, collects samples, and reports whether worker profiling is supported. Provides the performance.mark() and PerformanceObserver fallback chain.

Requires Document-Policy. The Self-Profiling API requires Document-Policy: js-profiling on the page. This lab reports main-thread and worker availability separately because a main-thread pass does not guarantee the worker global exposes Profiler.

API probes

Live profiler test (main thread + worker)

Profiler availability test
Click "Run profiler test" to probe the Self-Profiling API…

Fallback pattern

/* Detect Self-Profiling API (main thread) */ const HAS_PROFILER = typeof Profiler !== 'undefined'; /* Main-thread support does not prove worker support; test inside a Worker. */ const CAN_TEST_WORKER_PROFILING = HAS_PROFILER && typeof Worker !== 'undefined'; /* Profiler with fallback */ async function profileWork(label, fn) { if (HAS_PROFILER) { // Self-Profiling API — sample-based CPU attribution const profiler = new Profiler({ sampleInterval: 10, maxBufferSize: 1000 }); await fn(); const trace = await profiler.stop(); console.log(label + ': ' + trace.samples.length + ' samples'); return trace; } // Fallback: manual marks around the work performance.mark(label + ':start'); await fn(); performance.mark(label + ':end'); performance.measure(label, label + ':start', label + ':end'); const m = performance.getEntriesByName(label, 'measure')[0]; console.log(label + ': ' + m?.duration?.toFixed(2) + 'ms (no sample breakdown)'); return null; } /* Worker profiling (Chrome 147+) */ const workerCode = ` // In the worker — Profiler is available when the browser exposes worker // profiling and the page's Document-Policy opt-in is active. self.addEventListener('message', async (e) => { if (typeof Profiler === 'undefined') { self.postMessage({ error: 'Profiler not available in worker' }); return; } const p = new Profiler({ sampleInterval: 10, maxBufferSize: 500 }); // … do expensive work … const trace = await p.stop(); self.postMessage({ samples: trace.samples.length }); }); `; const blob = new Blob([workerCode], { type: 'application/javascript' }); const worker = new Worker(URL.createObjectURL(blob)); worker.postMessage('start');

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗