Sampling and bounded history
Each requestAnimationFrame callback reads performance.now(). The difference from the preceding callback is one frame interval. The refresh rate test waits for 45 usable intervals before publishing stable metrics and retains only the latest 180. A gap below 0.5 ms or above 250 ms is excluded. Once a baseline exists, intervals below half the window median are omitted only while they form no more than 20% of the sample; this removes a sparse duplicate/startup-style callback cluster without suppressing a sustained cadence change. The whole sample set is cleared whenever the document becomes hidden, which prevents a tab switch or sleeping computer from contaminating the next visible run.