From e0e676366834b44690d0056c70fb0cd474a51ab3 Mon Sep 17 00:00:00 2001 From: nieling1 <52280105+nieling1@users.noreply.github.com> Date: Mon, 17 Jul 2023 18:06:57 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=BD=EF=B8=8F=20requestIdleCallback=20a?= =?UTF-8?q?dd=20the=20polyfill=20of=20MessageChannel=20(#2475)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/prefetch.ts | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/prefetch.ts b/src/prefetch.ts index 6af7697..43a42f1 100644 --- a/src/prefetch.ts +++ b/src/prefetch.ts @@ -16,20 +16,39 @@ declare global { } } -// RIC and shim for browsers setTimeout() without it -const requestIdleCallback = - window.requestIdleCallback || - function requestIdleCallback(cb: CallableFunction) { - const start = Date.now(); - return setTimeout(() => { - cb({ - didTimeout: false, - timeRemaining() { - return Math.max(0, 50 - (Date.now() - start)); - }, - }); - }, 1); +function idleCall(cb: IdleRequestCallback, start: number) { + cb({ + didTimeout: false, + timeRemaining() { + return Math.max(0, 50 - (Date.now() - start)); + }, + }); +} + +// RIC and shim for browsers setTimeout() without it idle +let requestIdleCallback: (cb: IdleRequestCallback) => any; +if (typeof window.requestIdleCallback !== 'undefined') { + requestIdleCallback = window.requestIdleCallback; +} else if (typeof window.MessageChannel !== 'undefined') { + // The first recommendation is to use MessageChannel because + // it does not have the 4ms delay of setTimeout + const channel = new MessageChannel(); + const port = channel.port2; + const tasks: IdleRequestCallback[] = []; + channel.port1.onmessage = ({ data }) => { + const task = tasks.shift(); + if (!task) { + return; + } + idleCall(task, data.start); }; + requestIdleCallback = function(cb: IdleRequestCallback) { + tasks.push(cb); + port.postMessage({ start: Date.now() }); + }; +} else { + requestIdleCallback = (cb: IdleRequestCallback) => setTimeout(idleCall, 0, cb, Date.now()); +} declare global { interface Navigator {