fix(js): keep performance clock bounded

This commit is contained in:
SGavrl committed 2026-08-01 15:20:35 +00:00
1 parent cdab919599
commit d93ff517fc
2 files changed
+20 -6

No files matched your search

+6 -6
View File
@@ -5361,14 +5361,14 @@ globalThis.XMLSerializer = class XMLSerializer {
globalThis.performance = globalThis.performance || {
now: (function() {
// Monotonically non-decreasing: return the wall-clock offset, but never a
// value below the last one. The previous version added an uncapped per-call
// sub-millisecond bump that could exceed 1.0, so when the millisecond then
// ticked over and the bump reset to 0 the result went backwards.
var _last = 0;
// value below the last one. Equal readings are allowed, and avoiding a
// synthetic per-call increment keeps tight loops from advancing the clock
// faster than real elapsed time.
var _last = -Infinity;
return function() {
var ms = Date.now() - (globalThis.performance.timeOrigin || 0);
if (ms > _last) _last = ms;
else _last += 0.001; // same/earlier ms: advance by a tiny epsilon
if (ms < _last) return _last;
_last = ms;
return _last;
};
})(),
+14
View File
@@ -1330,6 +1330,20 @@ mod tests {
assert_eq!(violations.as_f64(), Some(0.0), "performance.now() went backwards");
}
#[test]
fn performance_now_does_not_outrun_elapsed_time() {
let mut rt = setup_runtime("<html><body></body></html>");
let lead = rt
.evaluate(
"(function(){for(var i=0;i<500000;i++)performance.now(); return performance.now()-(Date.now()-performance.timeOrigin);})()",
)
.unwrap();
assert!(
lead.as_f64().unwrap() <= 1.0,
"performance.now() advanced ahead of elapsed time: {lead}"
);
}
#[test]
fn test_document_title() {
let mut rt = setup_runtime("<html><head><title>Test</title></head><body></body></html>");