Orange textured background

Getting Started

Performance & Browser Compatibility

Collection runs in parallel across all signals. The numbers below are typical tier 1 times. Use background collection to make fingerprinting invisible to users.

Reviewed

Typical tier 1 collection time

BrowserTypical time
Chrome / Edge~1200 ms
Firefox~1400 ms
Safari~1600 ms

Overlap collection with page load

The fastest way to ship fingerprinting without adding perceived latency is to start collection the moment your script executes. Use createCollector, call start() at the top of your page-load handler, and await getResult() only when you actually need the value, for example on form submit or before an API call.

In a typical single-page app, by the time the user has interacted with the first screen, the 1.2 to 1.6 s collection window has already passed and getResult() returns immediately.

Overlapping slow collectors

Some slow collectors run their asynchronous work in two stages. An early, non-blocking stage kicks off the slow browser call (for example an RTCPeerConnection offer or a media-device enumeration) without waiting for it; a later stage awaits the result. Because every slow collector's early stage fires before any of the awaits, the slow calls run concurrently instead of one after another, and wall-clock collection time drops by roughly the latency of the slowest call rather than their sum.

The two-stage path is hash-identical to the simple one-stage path by construction, so a collector produces byte-identical output whichever form it uses. This is verified by unit test.

Not every slow collector benefits equally. Some do only a quick synchronous check up front and keep their real work in the later stage, because splitting it would change timing semantics or run into browser concurrency limits. Others do useful synchronous work up front to take advantage of the overlap window.

typescript
import { getFingerprint, createCollector } from 'doorman-benny'; // Background pattern: start early, await late.
const collector = createCollector();
collector.start();
//... page load, user interaction...
const result = await collector.getResult(); // Warmup opt-in: yield before sampling.
const stableResult = await getFingerprint({ warmup: true }); // Pipeline timing: profiling only.
const timed = await getFingerprint({ performance: true });
console.log(timed._pipeline?.collect); // collection step ms
console.log(timed._pipeline?.checks); // consistency+incognito+automation ms
console.log(timed._pipeline?.total); // end-to-end ms

The warmup option and performance option are independent; they can be combined.

Browser compatibility

BrowserSupport level
Chrome 90+Excellent
Edge 90+Excellent
Firefox 88+Good
Safari 14+Good
Mobile ChromeGood
Mobile SafariGood

Last reviewed 2026-06-04