From 98e234992b04612c18a37f7dc1efccee70ea28b8 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 23 Nov 2025 08:32:31 -0800 Subject: [PATCH 1/2] Prefer performance.now() over Date.now() performance.now() is faster than Date.now() as there's no need to consult the system clock. The more important part of this is that performance.now() is monotonic and is guaranteed to never to backwards. --- src/browser/TimeBasedDebouncer.ts | 4 ++-- src/common/TaskQueue.ts | 14 +++++++------- src/common/input/WriteBuffer.ts | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/browser/TimeBasedDebouncer.ts b/src/browser/TimeBasedDebouncer.ts index 707e25cbb7..4d7a65a1e9 100644 --- a/src/browser/TimeBasedDebouncer.ts +++ b/src/browser/TimeBasedDebouncer.ts @@ -45,7 +45,7 @@ export class TimeBasedDebouncer implements IRenderDebouncer { // Only refresh if the time since last refresh is above a threshold, otherwise wait for // enough time to pass before refreshing again. - const refreshRequestTime: number = Date.now(); + const refreshRequestTime: number = performance.now(); if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) { // Enough time has lapsed since the last refresh; refresh immediately this._lastRefreshMs = refreshRequestTime; @@ -57,7 +57,7 @@ export class TimeBasedDebouncer implements IRenderDebouncer { this._additionalRefreshRequested = true; this._refreshTimeoutID = window.setTimeout(() => { - this._lastRefreshMs = Date.now(); + this._lastRefreshMs = performance.now(); this._innerRefresh(); this._additionalRefreshRequested = false; this._refreshTimeoutID = undefined; // No longer need to clear the timeout diff --git a/src/common/TaskQueue.ts b/src/common/TaskQueue.ts index 29c29f6487..40cddffddb 100644 --- a/src/common/TaskQueue.ts +++ b/src/common/TaskQueue.ts @@ -74,14 +74,14 @@ abstract class TaskQueue implements ITaskQueue { let lastDeadlineRemaining = deadline.timeRemaining(); let deadlineRemaining = 0; while (this._i < this._tasks.length) { - taskDuration = Date.now(); + taskDuration = performance.now(); if (!this._tasks[this._i]()) { this._i++; } - // other than performance.now, Date.now might not be stable (changes on wall clock changes), - // this is not an issue here as a clock change during a short running task is very unlikely - // in case it still happened and leads to negative duration, simply assume 1 msec - taskDuration = Math.max(1, Date.now() - taskDuration); + // other than performance.now, performance.now might not be stable (changes on wall clock + // changes), this is not an issue here as a clock change during a short running task is very + // unlikely in case it still happened and leads to negative duration, simply assume 1 msec + taskDuration = Math.max(1, performance.now() - taskDuration); longestTask = Math.max(taskDuration, longestTask); // Guess the following task will take a similar time to the longest task in this batch, allow // additional room to try avoid exceeding the deadline @@ -116,9 +116,9 @@ export class PriorityTaskQueue extends TaskQueue { } private _createDeadline(duration: number): ITaskDeadline { - const end = Date.now() + duration; + const end = performance.now() + duration; return { - timeRemaining: () => Math.max(0, end - Date.now()) + timeRemaining: () => Math.max(0, end - performance.now()) }; } } diff --git a/src/common/input/WriteBuffer.ts b/src/common/input/WriteBuffer.ts index 3cfc3a8307..c93f92d3dc 100644 --- a/src/common/input/WriteBuffer.ts +++ b/src/common/input/WriteBuffer.ts @@ -137,7 +137,7 @@ export class WriteBuffer extends Disposable { * effectively lowering the redrawing needs, schematically: * * macroTask _innerWrite: - * if (Date.now() - (lastTime | 0) < WRITE_TIMEOUT_MS): + * if (performance.now() - (lastTime | 0) < WRITE_TIMEOUT_MS): * schedule microTask _innerWrite(lastTime) * else: * schedule macroTask _innerWrite(0) @@ -158,7 +158,7 @@ export class WriteBuffer extends Disposable { * Note, for pure sync code `lastTime` and `promiseResult` have no meaning. */ protected _innerWrite(lastTime: number = 0, promiseResult: boolean = true): void { - const startTime = lastTime || Date.now(); + const startTime = lastTime || performance.now(); while (this._writeBuffer.length > this._bufferOffset) { const data = this._writeBuffer[this._bufferOffset]; const result = this._action(data, promiseResult); @@ -186,7 +186,7 @@ export class WriteBuffer extends Disposable { * responsibility to slice hard work), but we can at least schedule a screen update as we * gain control. */ - const continuation: (r: boolean) => void = (r: boolean) => Date.now() - startTime >= WRITE_TIMEOUT_MS + const continuation: (r: boolean) => void = (r: boolean) => performance.now() - startTime >= WRITE_TIMEOUT_MS ? setTimeout(() => this._innerWrite(0, r)) : this._innerWrite(startTime, r); @@ -202,7 +202,7 @@ export class WriteBuffer extends Disposable { * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the * current microtask queue (executed before setTimeout). */ - // const continuation: (r: boolean) => void = Date.now() - startTime >= WRITE_TIMEOUT_MS + // const continuation: (r: boolean) => void = performance.now() - startTime >= WRITE_TIMEOUT_MS // ? r => setTimeout(() => this._innerWrite(0, r)) // : r => this._innerWrite(startTime, r); @@ -222,7 +222,7 @@ export class WriteBuffer extends Disposable { this._bufferOffset++; this._pendingData -= data.length; - if (Date.now() - startTime >= WRITE_TIMEOUT_MS) { + if (performance.now() - startTime >= WRITE_TIMEOUT_MS) { break; } } From 6468a78237b1f228551286e27f8ac29f755a0d54 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 23 Nov 2025 08:40:35 -0800 Subject: [PATCH 2/2] Fix comment lint --- src/common/input/WriteBuffer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/input/WriteBuffer.ts b/src/common/input/WriteBuffer.ts index c93f92d3dc..801cf3efba 100644 --- a/src/common/input/WriteBuffer.ts +++ b/src/common/input/WriteBuffer.ts @@ -202,7 +202,8 @@ export class WriteBuffer extends Disposable { * throughput by eval'ing `startTime` upfront pulling at least one more chunk into the * current microtask queue (executed before setTimeout). */ - // const continuation: (r: boolean) => void = performance.now() - startTime >= WRITE_TIMEOUT_MS + // const continuation: (r: boolean) => void = performance.now() - startTime >= + // WRITE_TIMEOUT_MS // ? r => setTimeout(() => this._innerWrite(0, r)) // : r => this._innerWrite(startTime, r);