From 85387998351158aacda459146292c617d47e6965 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 9 Oct 2024 16:32:28 -0700 Subject: [PATCH 1/9] Leverage scheduler.yield in splitTask when available --- packages/interactivity/src/utils.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index c5eb91681294f2..97aec7c46d4f6f 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -49,9 +49,19 @@ const afterNextFrame = ( callback: () => void ) => { * @return Promise */ export const splitTask = () => { - return new Promise( ( resolve ) => { - // TODO: Use scheduler.yield() when available. - setTimeout( resolve, 0 ); + return new Promise( async ( resolve ) => { + if ( + 'scheduler' in window && + typeof window.scheduler === 'object' && + null !== window.scheduler && + 'yield' in window.scheduler && + typeof window.scheduler.yield === 'function' + ) { + await window.scheduler.yield(); + resolve( undefined ); + } else { + setTimeout( resolve, 0 ); + } } ); }; From 70077b87144396c3bb5e5ae3211c8ebf1bf66b49 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 11:17:14 -0700 Subject: [PATCH 2/9] Eliminate extra Promise when using scheduler.yield() Co-authored-by: swissspidy --- packages/interactivity/src/utils.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index 97aec7c46d4f6f..baeb07636c83c5 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -49,19 +49,17 @@ const afterNextFrame = ( callback: () => void ) => { * @return Promise */ export const splitTask = () => { + if ( + 'scheduler' in window && + typeof window.scheduler === 'object' && + null !== window.scheduler && + 'yield' in window.scheduler && + typeof window.scheduler.yield === 'function' + ) { + return window.scheduler.yield(); + } return new Promise( async ( resolve ) => { - if ( - 'scheduler' in window && - typeof window.scheduler === 'object' && - null !== window.scheduler && - 'yield' in window.scheduler && - typeof window.scheduler.yield === 'function' - ) { - await window.scheduler.yield(); - resolve( undefined ); - } else { - setTimeout( resolve, 0 ); - } + setTimeout( resolve, 0 ); } ); }; From d5c51a67c641c1980225ae21f5b7c084de8b9af2 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 11:44:29 -0700 Subject: [PATCH 3/9] Avoid needlessly re-checking whether scheduler.yield() is defined --- packages/interactivity/src/utils.ts | 36 ++++++++++++++++++----------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index baeb07636c83c5..1c48941e2bd1b9 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -22,6 +22,14 @@ interface Flusher { readonly dispose: () => void; } +declare global { + interface Window { + scheduler: { + readonly yield: () => void; + }; + } +} + /** * Executes a callback function after the next frame is rendered. * @@ -48,20 +56,20 @@ const afterNextFrame = ( callback: () => void ) => { * * @return Promise */ -export const splitTask = () => { - if ( - 'scheduler' in window && - typeof window.scheduler === 'object' && - null !== window.scheduler && - 'yield' in window.scheduler && - typeof window.scheduler.yield === 'function' - ) { - return window.scheduler.yield(); - } - return new Promise( async ( resolve ) => { - setTimeout( resolve, 0 ); - } ); -}; +export const splitTask = + 'scheduler' in window && + typeof window.scheduler === 'object' && + null !== window.scheduler && + 'yield' in window.scheduler && + typeof window.scheduler.yield === 'function' + ? () => { + return window.scheduler.yield(); + } + : () => { + return new Promise( async ( resolve ) => { + setTimeout( resolve, 0 ); + } ); + }; /** * Creates a Flusher object that can be used to flush computed values and notify listeners. From 2516cd43c54742af676dd9d7837e9b56859b1016 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 11:46:51 -0700 Subject: [PATCH 4/9] Remove needless function wrapper --- packages/interactivity/src/utils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index 1c48941e2bd1b9..1f2d6705c5182d 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -62,9 +62,7 @@ export const splitTask = null !== window.scheduler && 'yield' in window.scheduler && typeof window.scheduler.yield === 'function' - ? () => { - return window.scheduler.yield(); - } + ? window.scheduler.yield : () => { return new Promise( async ( resolve ) => { setTimeout( resolve, 0 ); From a0933f4a6dd7763a406109491b928a480a85de51 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 12:16:26 -0700 Subject: [PATCH 5/9] Ensure that scheduler is context object to yield function --- packages/interactivity/src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index 1f2d6705c5182d..a9ba20161c4df8 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -62,7 +62,7 @@ export const splitTask = null !== window.scheduler && 'yield' in window.scheduler && typeof window.scheduler.yield === 'function' - ? window.scheduler.yield + ? window.scheduler.yield.bind( window.scheduler ) : () => { return new Promise( async ( resolve ) => { setTimeout( resolve, 0 ); From ee36a344a345d4eb2f773ddee8570285bac2283a Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 12:17:34 -0700 Subject: [PATCH 6/9] Remove needless async --- packages/interactivity/src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index a9ba20161c4df8..ea82ac9b26cb99 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -64,7 +64,7 @@ export const splitTask = typeof window.scheduler.yield === 'function' ? window.scheduler.yield.bind( window.scheduler ) : () => { - return new Promise( async ( resolve ) => { + return new Promise( ( resolve ) => { setTimeout( resolve, 0 ); } ); }; From 0abf7befe916e797c8ca297f0c359a2eb648928c Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 13:28:40 -0700 Subject: [PATCH 7/9] Reduce verbosity of scheduler.yield() existence check --- packages/interactivity/src/utils.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index ea82ac9b26cb99..0f48890a9ad976 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -57,11 +57,7 @@ const afterNextFrame = ( callback: () => void ) => { * @return Promise */ export const splitTask = - 'scheduler' in window && - typeof window.scheduler === 'object' && - null !== window.scheduler && - 'yield' in window.scheduler && - typeof window.scheduler.yield === 'function' + typeof window.scheduler?.yield === 'function' ? window.scheduler.yield.bind( window.scheduler ) : () => { return new Promise( ( resolve ) => { From be4ceff0dea550711eb77d079ff665cd05fa8c19 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 13:33:36 -0700 Subject: [PATCH 8/9] Fix return type for scheduler.yield() Co-authored-by: Brendan Kenny --- packages/interactivity/src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index 0f48890a9ad976..209e320a753bd2 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -25,7 +25,7 @@ interface Flusher { declare global { interface Window { scheduler: { - readonly yield: () => void; + readonly yield: () => Promise; }; } } From 3d40b9f37427f4bc309330853bcb6394def37e08 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 10 Oct 2024 13:35:11 -0700 Subject: [PATCH 9/9] Define scheduler and scheduler.yield as optional Co-authored-by: Brendan Kenny --- packages/interactivity/src/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/interactivity/src/utils.ts b/packages/interactivity/src/utils.ts index 209e320a753bd2..a0ad36d560e56b 100644 --- a/packages/interactivity/src/utils.ts +++ b/packages/interactivity/src/utils.ts @@ -24,8 +24,8 @@ interface Flusher { declare global { interface Window { - scheduler: { - readonly yield: () => Promise; + scheduler?: { + readonly yield?: () => Promise< void >; }; } }