a stylesheet that provably loaded appears in the performance timeline
Check id resource-timing-vs-cssom
What an ordinary browser yields
A stylesheet that demonstrably fetched and parsed also appears in the performance timeline, alongside the other resources the timeline is already reporting.
What a detector infers
Fetching a resource writes two records: the DOM object you can see, and an immutable entry in the performance timeline. PerimeterX ships the diff of those two ledgers in every payload — a count walked off document.styleSheets next to a count taken from the Resource Timing API — because a mismatch means someone is editing one book and not the other. A harness that injects a script and then filters performance.getEntries() to hide it has not removed the resource; it has created a contradiction between the page's two accounts of what it downloaded. This check is also the clearest example on the page of why reading a detector's collection list is not the same as inheriting its inferences. Running PerimeterX's own counting function verbatim on an ordinary site gives 47 against 17, because @import'd and CSS-initiated subresources carry the css initiator type without being top-level stylesheet entries. Asserting count equality — the naive reading of the two fields — would flag the entire web. PerimeterX never asserts it client-side; it ships raw counts for a backend to score. So this does the opposite: it injects ONE probe of its own at a cache-busted same-origin URL, proves with the load event and readable cssRules that a real fetch and parse happened, and only then requires the timeline to contain it — and only once the timeline has already proven it reports other resources at all. It uses a PerformanceObserver rather than getEntriesByType because the resource buffer holds 250 entries and silently drops the rest, and this page fires enough probes to overflow it. The honest way to build a check like this is to make the browser calibrate it, and to refuse to speak unless the browser has shown you it answers this question at all.
How to resolve it
Nothing needs fixing when the two agree. If they disagree, the performance timeline is being filtered while the DOM is not — and the timeline is an append-only ledger, so hiding an entry from it is a contradiction rather than a removal. Note this check compares one specific URL and never the counts: @import'd and CSS-initiated subresources make the totals differ on perfectly ordinary sites.
Read in the wild by
PerimeterX / HUMAN
Counts the page's stylesheets two independent ways inside a single function — once by walking document.styleSheets for entries carrying an href, once by walking performance.getEntriesByType("resource") for css initiators and link initiators whose URL ends in .css — and ships both totals as separate raw fields, alongside image and font counts taken from the same resource-timing walk. The function returns the counts without ever comparing them client-side; whatever is made of the discrepancy happens server-side.
warterbili/PerimeterX_RE, stample/ifood/source/main.min.js (deployed collector, _pxAppId "PXO1GDTa7Q"): `function jT(){for(var t=hT[hN(109)],n={cssFromStyleSheets:0},e=0;e<t.length;e++){t[e].href&&n.cssFromStyleSheets++}if(jU()){…var r=hS[hN(110)].getEntriesByType("resource");n.imgFromResourceApi=0,n.cssFromResourceApi=0,n.fontFromResourceApi=0;for(var h=0;h<r.length;h++){var i=r[h];i.initiatorType===hN(111)&&n.imgFromResourceApi++,("css"===i.initiatorType||"link"===i.initiatorType&&-1!==i.name.indexOf(".css"))&&n.cssFromResourceApi++,"link"===i.initiatorType&&-1!==i.name.indexOf(".woff")&&n.fontFromResourceApi++}}return n}` — where hT=document, hS=window, and the script's own string table decodes hN(109)="styleSheets", hN(110)="performance", hN(111)="img". The same function appears deobfuscated at bundle/source/main_legacy_with_captcha.js:539-556 (`e=a.styleSheets`, `r.performance.getEntriesByType("resource")`). Emitted as EV2 in bug_report/sdk_drift_cases/2026-05-19_ifood/all_fields_map.json: "HCgpIlpJKxk=" = 3 (cssFromStyleSheets) beside "RlZzHAA6eC8=" = 3 (cssFromResourceApi), plus "PSkIY3tECVY=" = 0 (imgFromResourceApi) and "UBxlVhZ/ZGY=" = 8 (fontFromResourceApi).
Every attribution traces to a published artifact. See the sources and their limits.
Other checks in Clocks & ledgers
- the monotonic clock and the wall clock name the same instant
epoch-vs-monotonic-clockA browser carries two physically different clocks: a monotonic counter anchored at performance.timeOrigin, and the wall clock behind… - both generations of the navigation timing API describe the same page load
navigation-timing-dual-apiThe platform kept two generations of one API alive. performance.timing speaks Unix epoch; PerformanceNavigationTiming speaks milliseconds… - wall-clock and monotonic time advance at the same rate
wallclock-vs-monotonic-rateA browser owns two clocks and they are not the same clock. Date.now() is wall time: it can be wrong, it can be corrected, it can jump… - PerformanceEntry timestamps land on the same grid performance.now() exhibits
perf-clock-grid-coherenceA timestamp's low bits are a fingerprint. DataDome ships its performance floats unrounded — 2253.7000000029802 rather than 2253.7 — and that… - every surface that reports when this document started agrees
navigation-origin-consensusOne document has one navigation start, and Chrome exposes it through four different doors: performance.timeOrigin, the legacy…
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Clocks & ledgers checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Clocks & ledgers — the family resource-timing-vs-cssom belongs to.