javascript - Deferring Script wp-i18n causes a console error 'wp is not defined' - Gravityforms

admin2025-01-08  5

I am deferring JS scripts in order to optimize page load times and SEO. My code to defer scripts is something like:

add_filter(
    'script_loader_tag', // Filters the HTML script tag of an enqueued script.
    function ( $tag, $handle ) {
        return str_replace( ' src', ' defer="defer" src', $tag );
    }
);

It works fine for most scripts. However, when it defers scripts like wp-i18n, it causes the error because of the -js-after code that it tries to run before the it executes the deferred script.

<script type='text/javascript' defer="defer" src='http://192.168.1.71/wp-includes/js/dist/i18n.min.js?ver=db9a9a37da262883343e941c3731bc67' id='wp-i18n-js'></script>
<script type='text/javascript' id='wp-i18n-js-after'>
wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
</script>

It seems the problem is that the script is deferred in contrast to its -js-after script. I need a solution that does one of the following.

  • Skips deferring scripts that have a -js-after
  • Deferrs the js-after along with the script.

Implementing the first option using using

$data = $wp_scripts->get_data( 'wp-i18n', 'data' );

does not work because $data does not contain information as to whether the script has a -js-after. Searching for "detecting 'WordPress -js-after'" does not give any helpful results.

I am deferring JS scripts in order to optimize page load times and SEO. My code to defer scripts is something like:

add_filter(
    'script_loader_tag', // Filters the HTML script tag of an enqueued script.
    function ( $tag, $handle ) {
        return str_replace( ' src', ' defer="defer" src', $tag );
    }
);

It works fine for most scripts. However, when it defers scripts like wp-i18n, it causes the error because of the -js-after code that it tries to run before the it executes the deferred script.

<script type='text/javascript' defer="defer" src='http://192.168.1.71/wp-includes/js/dist/i18n.min.js?ver=db9a9a37da262883343e941c3731bc67' id='wp-i18n-js'></script>
<script type='text/javascript' id='wp-i18n-js-after'>
wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
</script>

It seems the problem is that the script is deferred in contrast to its -js-after script. I need a solution that does one of the following.

  • Skips deferring scripts that have a -js-after
  • Deferrs the js-after along with the script.

Implementing the first option using using

$data = $wp_scripts->get_data( 'wp-i18n', 'data' );

does not work because $data does not contain information as to whether the script has a -js-after. Searching for "detecting 'WordPress -js-after'" does not give any helpful results.

Share Improve this question edited Aug 3, 2021 at 15:27 Meyer Auslander - Tst asked Aug 2, 2021 at 19:58 Meyer Auslander - TstMeyer Auslander - Tst 311 silver badge5 bronze badges 5
  • 2 I'm assuming this is on the frontend? Not all javascript can or should be deferred, and js-after isn't what you should be looking for, these look to be scripts added via wp_add_inline_script. Can an inline script even be deferred? I don't think it makes sense – Tom J Nowell Commented Aug 2, 2021 at 20:26
  • Yes this is for the frontend. enqueue of wp-i18n triggers the added inline script. When wp-i18n gets deferred, which it can be deferred, it causes the error. Is there a way to detect if a script like wp-i18n has a corresponding inline script? What should I be looking for? Should I just hard code wp-i18n not to be deferred? What about others that are similar? – Meyer Auslander - Tst Commented Aug 2, 2021 at 21:43
  • 1 Gravityforms plugin has $assets[] = new GF_Script_Asset( 'wp-a11y' ); in form_display.php. wp-i18n is a dependency of wp-a11y. Therefore it comes out wp-i18n is enqueued on the frontend when there is a form display. – Meyer Auslander - Tst Commented Aug 3, 2021 at 15:25
  • In general, I'd probably seek to manually choose which scripts are deferred rather than attempting to defer them all and except some few - as Tom implies, it can break a lot of things. It's probably possible to discern which scripts have wp_add_inline_script()/wp_localize_script() inline dependencies by digging through the registry in the $wp_scripts global, probably at both the wp_print_scripts action as well as wp_footer. – bosco Commented Aug 3, 2021 at 15:56
  • You defer a script if it can be loaded later. If there's a script that depends on it, then it can't be loaded later and shouldn't be deferred. – Jacob Peattie Commented Aug 4, 2021 at 10:06
Add a comment  | 

1 Answer 1

Reset to default 3

It is necessary to exclude defer addition for files that have -js-after In my case, the error was caused by the files hooks.min.js and i18n.min.js.

This function worked great in my case:

function defer_parsing_of_js( $url ) {

    if ( is_user_logged_in() ) return $url; //don't break WP Admin
    if ( FALSE === strpos( $url, '.js' ) ) return $url;
    if ( strpos( $url, "jquery.min.js" ) || strpos( $url, "jquery-migrate.min.js" ) || strpos( $url, "hooks.min.js" ) || strpos( $url, "i18n.min.js" )) {
        return $url;
    }
    
    return str_replace( ' src', ' defer src', $url );
}                                        
add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 ); 
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736269310a1342.html

最新回复(0)