How many times the recent median an interval must exceed to count as dead time (default 4)
How many PRECEDING intervals the median is taken
over (default 4 — short enough to follow a real slowdown within a
few frames, long enough that one hitch cannot move the median, and
EVEN so a 1:1 alternating cadence converges; see the class
comment). CLAMPED to at least 2: a windowSize of 0 leaves the
memory permanently empty, so every over-floor interval takes the
cold-memory path and the absolute-threshold-only rule this class
exists to replace is silently back, while 1 leaves a memory that
follows every single hitch. outlierFactor is likewise clamped to
at least 1.
A NON-FINITE knob is treated as ABSENT and falls back to the default
BEFORE the clamp, because Math.max propagates NaN rather than
rejecting it: Math.max(2, NaN) is NaN, and a NaN windowSize
would leave recent.length > NaN permanently false — the ring
never trims, so it grows without bound and pays an O(n log n) median
on every frame — while a NaN outlierFactor makes every comparison
false and the detector never fires at all. ±Infinity is just as
bad (an infinite ring, or a factor nothing can exceed), so the guard
is Number.isFinite, not an isNaN check. minGapMs needs it
MOST: !(intervalMs > NaN) is true for every interval, so a NaN
floor makes isStall answer false forever — dead time is never
discarded at all and a single tab-resume gap folds into the FPS
window of an otherwise healthy 60 fps session.
Private ReadonlyrecentIntervals PRECEDING the next one to judge, oldest first (≤ windowSize).
Private ReadonlyminPrivate ReadonlyoutlierPrivate ReadonlywindowFeed the next inter-frame interval; true when it is DEAD TIME rather than the frame rate.
Every interval must be fed, stall or not — the median is the memory that lets the next call tell the two apart.
PrivateclassifyThe verdict for intervalMs, judged against the PRECEDING cadence
only — the interval never contributes to the median it is compared
against (see the class comment).
PrivaterememberRetain the interval as a neighbour for subsequent verdicts.
PrivatemedianMedian of the retained intervals (mean of the middle two if even).
Forget the cadence (display change, disable, pause, dispose). NOT called by the gap reset itself, nor by a content change — see the class comment.
Absolute floor: an interval at or under this is never dead time, however large the outlier ratio