Skip to content

Commit f03cacc

Browse files
committed
feat: implement IdleModule for executing tasks during browser idle time
1 parent 3dab92e commit f03cacc

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

app/material-icons/material-icons.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {ComponentModule} from "../../src/modules/component.js";
22
import "./../../components/material-icon/material-icon.js";
33
import {icons} from "./icons.js";
44
import { EventsManager } from "../../src/system/events-manager.js";
5+
import {IdleModule} from "./../../src/modules/idle.js";
56

67
export default class MaterialIconsView extends HTMLElement {
78
static tag = "material-icons-view";
@@ -18,7 +19,7 @@ export default class MaterialIconsView extends HTMLElement {
1819
url: import.meta.url,
1920
});
2021

21-
this.#createIcons();
22+
IdleModule.perform({tasks: [this.#createIcons.bind(this)]});
2223
this.#setupSearch();
2324
}
2425

src/modules/idle.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { validateArgs } from "./../validate/validate-args.js";
2+
3+
export class IdleModule {
4+
static name = Object.freeze("idle");
5+
6+
static perform(args) {
7+
validateArgs(args, {
8+
tasks: { type: "Array", required: true }
9+
}, "IdleModule.initialize: ");
10+
11+
return globalThis.idleWorker.perform(args.tasks);
12+
}
13+
}
14+
15+
/**
16+
* This class is responsible for executing tasks when the browser is idle.
17+
* It maintains a queue of tasks to be executed when the browser is idle.
18+
*/
19+
class IdleWorker {
20+
#queue = [];
21+
#idleCallbackId = null;
22+
23+
/**
24+
* Perform the first task in the queue.
25+
* @returns
26+
*/
27+
#performFirstTask(deadline) {
28+
while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && this.#queue.length > 0) {
29+
const task = this.#queue.shift();
30+
task();
31+
}
32+
33+
if (this.#queue.length > 0) {
34+
this.#idleCallbackId = requestIdleCallback(this.#performFirstTask.bind(this));
35+
} else {
36+
this.#idleCallbackId = null;
37+
}
38+
}
39+
40+
perform(tasks) {
41+
this.#queue.push(...tasks);
42+
this.#startIdleTaskExecution();
43+
}
44+
45+
#startIdleTaskExecution() {
46+
if (this.#idleCallbackId === null) {
47+
this.#idleCallbackId = requestIdleCallback(this.#performFirstTask.bind(this));
48+
}
49+
}
50+
}
51+
52+
globalThis.idleWorker ||= new IdleWorker();

0 commit comments

Comments
 (0)