Skip to content

Delay loading detect module until page is loaded and idle #2017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions plugins/optimization-detective/detect-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Loads the detect logic after the page has loaded to prevent a high-priority script module network request from competing with other critical resources.
*
* This JavaScript file must be contain a single top-level function which is not exported. The file is inlined as part of another module which wraps the module in an IIFE.
*
* @param {string} detectSrc
* @param {Object} detectArgs
*/
// eslint-disable-next-line no-unused-vars
async function load( detectSrc, detectArgs ) {
const doc = document;
const win = window;

// Ensure the DOM is loaded (although it surely already is since we're executing in a module).
await new Promise( ( resolve ) => {
if ( doc.readyState !== 'loading' ) {
resolve();
} else {
doc.addEventListener( 'DOMContentLoaded', resolve, { once: true } );
}
} );

// Wait until the resources on the page have fully loaded.
await new Promise( ( resolve ) => {
if ( doc.readyState === 'complete' ) {
resolve();
} else {
win.addEventListener( 'load', resolve, { once: true } );
}
} );

// Wait yet further until idle.
if ( typeof requestIdleCallback === 'function' ) {
await new Promise( ( resolve ) => {
requestIdleCallback( resolve );
} );
}

const { default: detect } = await import( detectSrc );
await detect( detectArgs );
}
25 changes: 0 additions & 25 deletions plugins/optimization-detective/detect.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,31 +635,6 @@ export default async function detect( {
return;
}

// Ensure the DOM is loaded (although it surely already is since we're executing in a module).
await new Promise( ( resolve ) => {
if ( doc.readyState !== 'loading' ) {
resolve();
} else {
doc.addEventListener( 'DOMContentLoaded', resolve, { once: true } );
}
} );

// Wait until the resources on the page have fully loaded.
await new Promise( ( resolve ) => {
if ( doc.readyState === 'complete' ) {
resolve();
} else {
win.addEventListener( 'load', resolve, { once: true } );
}
} );

// Wait yet further until idle.
if ( typeof requestIdleCallback === 'function' ) {
await new Promise( ( resolve ) => {
requestIdleCallback( resolve );
} );
}

// TODO: Does this make sense here? Should it be moved up above the isViewportNeeded condition?
// As an alternative to this, the od_print_detection_script() function can short-circuit if the
// od_is_url_metric_storage_locked() function returns true. However, the downside with that is page caching could
Expand Down
3 changes: 2 additions & 1 deletion plugins/optimization-detective/detection.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ static function ( OD_URL_Metric_Group $group ): array {

return wp_get_inline_script_tag(
sprintf(
'import detect from %s; detect( %s );',
'( %s )( %s, %s );',
file_get_contents( __DIR__ . '/' . od_get_asset_path( 'detect-loader.js' ) ), // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- It's a local filesystem path not a remote request.
wp_json_encode( plugins_url( add_query_arg( 'ver', OPTIMIZATION_DETECTIVE_VERSION, od_get_asset_path( 'detect.js' ) ), __FILE__ ) ),
wp_json_encode( $detect_args )
),
Expand Down
4 changes: 4 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ const optimizationDetective = ( env ) => {
cache: false,
},
},
{
from: `${ destination }/detect-loader.js`,
to: `${ destination }/detect-loader.min.js`,
},
{
from: `${ destination }/detect.js`,
to: `${ destination }/detect.min.js`,
Expand Down
Loading