summaryrefslogtreecommitdiff
path: root/packages/frontend/src/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/frontend/src/scripts')
-rw-r--r--packages/frontend/src/scripts/idle-render.ts38
1 files changed, 38 insertions, 0 deletions
diff --git a/packages/frontend/src/scripts/idle-render.ts b/packages/frontend/src/scripts/idle-render.ts
new file mode 100644
index 0000000000..ccce8b02bf
--- /dev/null
+++ b/packages/frontend/src/scripts/idle-render.ts
@@ -0,0 +1,38 @@
+class IdlingRenderScheduler {
+ #renderers: Set<FrameRequestCallback>;
+ #rafId: number;
+ #ricId: number;
+
+ constructor() {
+ this.#renderers = new Set();
+ this.#rafId = 0;
+ this.#ricId = requestIdleCallback((deadline) => this.#schedule(deadline));
+ }
+
+ #schedule(deadline: IdleDeadline): void {
+ if (deadline.timeRemaining()) {
+ this.#rafId = requestAnimationFrame((time) => {
+ for (const renderer of this.#renderers) {
+ renderer(time);
+ }
+ });
+ }
+ this.#ricId = requestIdleCallback((arg) => this.#schedule(arg));
+ }
+
+ add(renderer: FrameRequestCallback): void {
+ this.#renderers.add(renderer);
+ }
+
+ delete(renderer: FrameRequestCallback): void {
+ this.#renderers.delete(renderer);
+ }
+
+ dispose(): void {
+ this.#renderers.clear();
+ cancelAnimationFrame(this.#rafId);
+ cancelIdleCallback(this.#ricId);
+ }
+}
+
+export const defaultIdlingRenderScheduler = new IdlingRenderScheduler();