diff --git a/packages/interactivity/CHANGELOG.md b/packages/interactivity/CHANGELOG.md index 0c627c9f640c59..49b6b28b91a96f 100644 --- a/packages/interactivity/CHANGELOG.md +++ b/packages/interactivity/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancements + +- Break up init with yielding to main to prevent long task from hydration. ([#58227](https://github.com/WordPress/gutenberg/pull/58227)) + ## 4.0.0 (2024-01-24) ### Enhancements diff --git a/packages/interactivity/src/init.js b/packages/interactivity/src/init.js index d749003b86f49d..839302c4f8c6b2 100644 --- a/packages/interactivity/src/init.js +++ b/packages/interactivity/src/init.js @@ -21,15 +21,26 @@ export const getRegionRootFragment = ( region ) => { return regionRootFragments.get( region ); }; +function yieldToMain() { + return new Promise( ( resolve ) => { + // TODO: Use scheduler.yield() when available. + setTimeout( resolve, 0 ); + } ); +} + // Initialize the router with the initial DOM. export const init = async () => { - document - .querySelectorAll( `[data-${ directivePrefix }-interactive]` ) - .forEach( ( node ) => { - if ( ! hydratedIslands.has( node ) ) { - const fragment = getRegionRootFragment( node ); - const vdom = toVdom( node ); - hydrate( vdom, fragment ); - } - } ); + const nodes = document.querySelectorAll( + `[data-${ directivePrefix }-interactive]` + ); + + for ( const node of nodes ) { + if ( ! hydratedIslands.has( node ) ) { + await yieldToMain(); + const fragment = getRegionRootFragment( node ); + const vdom = toVdom( node ); + await yieldToMain(); + hydrate( vdom, fragment ); + } + } };