Skip to content

Commit e0e6763

Browse files
authored
👽️ requestIdleCallback add the polyfill of MessageChannel (#2475)
1 parent f17b416 commit e0e6763

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

src/prefetch.ts

+32-13
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,39 @@ declare global {
1616
}
1717
}
1818

19-
// RIC and shim for browsers setTimeout() without it
20-
const requestIdleCallback =
21-
window.requestIdleCallback ||
22-
function requestIdleCallback(cb: CallableFunction) {
23-
const start = Date.now();
24-
return setTimeout(() => {
25-
cb({
26-
didTimeout: false,
27-
timeRemaining() {
28-
return Math.max(0, 50 - (Date.now() - start));
29-
},
30-
});
31-
}, 1);
19+
function idleCall(cb: IdleRequestCallback, start: number) {
20+
cb({
21+
didTimeout: false,
22+
timeRemaining() {
23+
return Math.max(0, 50 - (Date.now() - start));
24+
},
25+
});
26+
}
27+
28+
// RIC and shim for browsers setTimeout() without it idle
29+
let requestIdleCallback: (cb: IdleRequestCallback) => any;
30+
if (typeof window.requestIdleCallback !== 'undefined') {
31+
requestIdleCallback = window.requestIdleCallback;
32+
} else if (typeof window.MessageChannel !== 'undefined') {
33+
// The first recommendation is to use MessageChannel because
34+
// it does not have the 4ms delay of setTimeout
35+
const channel = new MessageChannel();
36+
const port = channel.port2;
37+
const tasks: IdleRequestCallback[] = [];
38+
channel.port1.onmessage = ({ data }) => {
39+
const task = tasks.shift();
40+
if (!task) {
41+
return;
42+
}
43+
idleCall(task, data.start);
44+
};
45+
requestIdleCallback = function(cb: IdleRequestCallback) {
46+
tasks.push(cb);
47+
port.postMessage({ start: Date.now() });
3248
};
49+
} else {
50+
requestIdleCallback = (cb: IdleRequestCallback) => setTimeout(idleCall, 0, cb, Date.now());
51+
}
3352

3453
declare global {
3554
interface Navigator {

0 commit comments

Comments
 (0)