Skip to content

Instantly share code, notes, and snippets.

@futtta
Last active November 11, 2022 21:43
Show Gist options
  • Save futtta/01ba20efa0893edb52b0a233a5c05ae8 to your computer and use it in GitHub Desktop.
Save futtta/01ba20efa0893edb52b0a233a5c05ae8 to your computer and use it in GitHub Desktop.
POC to defer inline JS that requires jQuery
<?php
add_action('plugins_loaded','ao_defer_inline_init');
function ao_defer_inline_init() {
if ( get_option('autoptimize_js_include_inline') != 'on' ) {
add_filter('autoptimize_html_after_minify','ao_defer_inline_jquery',10,1);
}
}
function ao_defer_inline_jquery( $in ) {
if ( preg_match_all( '#<script.*>(.*)</script>#Usmi', $in, $matches, PREG_SET_ORDER ) ) {
foreach( $matches as $match ) {
if ( $match[1] !== '' && ( strpos( $match[1], 'jQuery' ) !== false || strpos( $match[1], '$' ) !== false ) ) {
// inline js that requires jquery, wrap deferring JS around it to defer it.
$new_match = 'var aoDeferInlineJQuery=function(){'.$match[1].'}; if (document.readyState === "loading") {document.addEventListener("DOMContentLoaded", aoDeferInlineJQuery);} else {aoDeferInlineJQuery();}';
$in = str_replace( $match[1], $new_match, $in );
} else if ( $match[1] === '' && strpos( $match[0], 'src=' ) !== false && strpos( $match[0], 'defer' ) === false ) {
// linked non-aggregated JS, defer it.
$new_match = str_replace( '<script ', '<script defer ', $match[0] );
$in = str_replace( $match[0], $new_match, $in );
}
}
}
return $in;
}
@SciLor
Copy link

SciLor commented Feb 6, 2019

Works great. for me. I had to add recaptcha to make it work.

@figarro
Copy link

figarro commented Oct 31, 2019

Is there a way to hook add_filter to something that's WordPress native and does not depend on the Autoptimize plugin?

@futtta
Copy link
Author

futtta commented Oct 31, 2019

I don't think WordPress native has a filter for the full HTML @figgaro, but if you're using a page caching plugin then that probably has a filter that allows the same.

@niamrox
Copy link

niamrox commented Apr 30, 2020

Did not work for me !

@roytuts
Copy link

roytuts commented May 27, 2020

Did not work for me

@Rajesh-Royal
Copy link

worked!
Now I'm loading jquery deferred in Avada theme and got no problem also revolution slider revolution slider.

@robertparkerx
Copy link

robertparkerx commented Aug 5, 2020

EDIT: It's working!

@devhelper
Copy link

it's not working after update to WP 5.5

@hadadjus
Copy link

hadadjus commented Sep 6, 2020

wp-content/themes/my theme/functions.php. Error message: syntax error, unexpected 'if' (T_IF) how to solve please i want to hide weird unstyled flashing issue in first second?

@Rajesh-Royal
Copy link

wp-content/themes/my theme/functions.php. Error message: syntax error, unexpected 'if' (T_IF) how to solve please i want to hide weird unstyled flashing issue in first second?

you have to include complete snippet or post more detail before we can help, it may look like you missed a syntax in php

@hadadjus
Copy link

hadadjus commented Sep 6, 2020

im using this tutorial https://wpsoul.com/how-optimize-speed-of-wordpress/#setup-database-and-file-cache-with-cache-plugins to optimise my site when i put the the php code in the function file i get this error wp-content/themes/my theme/functions.php. Error message: syntax error, unexpected 'if' (T_IF) and my site got error 500

@Rajesh-Royal
Copy link

add_action('plugins_loaded','ao_defer_inline_init');

function ao_defer_inline_init() {
	if ( get_option('autoptimize_js_include_inline') != 'on' ) {
		add_filter('autoptimize_html_after_minify','ao_defer_inline_jquery',10,1);
	}
}

function ao_defer_inline_jquery( $in ) {
  if ( preg_match_all( '#<script.*>(.*)</script>#Usmi', $in, $matches, PREG_SET_ORDER ) ) {
    foreach( $matches as $match ) {
      if ( $match[1] !== '' && ( strpos( $match[1], 'jQuery' ) !== false || strpos( $match[1], '$' ) !== false ) ) {
        // inline js that requires jquery, wrap deferring JS around it to defer it. 
        $new_match = 'var aoDeferInlineJQuery=function(){'.$match[1].'}; if (document.readyState === "loading") {document.addEventListener("DOMContentLoaded", aoDeferInlineJQuery);} else {aoDeferInlineJQuery();}';
        $in = str_replace( $match[1], $new_match, $in );
      } else if ( $match[1] === '' && strpos( $match[0], 'src=' ) !== false && strpos( $match[0], 'defer' ) === false ) {
        // linked non-aggregated JS, defer it.
        $new_match = str_replace( '<script ', '<script defer ', $match[0] );
        $in = str_replace( $match[0], $new_match, $in );
      }
    }
  }
  return $in;
}

use this code.

@Rajesh-Royal
Copy link

put this code at the very end of function.php to avoid accidental syntax errors.

@hadadjus
Copy link

hadadjus commented Sep 6, 2020

i puted it in at once in the begin of function not worked i puted itin the last too not worked i got this error in my site " There has been a critical error on your website. " :'(

@AkshanAgarwal
Copy link

So should i put this code at the end of my functions.php? will this solve the render blocking alert related to jquery on pagespeeds ?

@adonix31
Copy link

adonix31 commented Feb 3, 2021

I added this code to my functions.php, but nothing is happening. I have Autoptimize and Async JavaScript plugins. Both have jQuery excluded for correct functioning of the site. What could be the culprit here?
Thanks

@deewinc
Copy link

deewinc commented May 16, 2021

So should i put this code at the end of my functions.php? will this solve the render blocking alert related to jquery on pagespeeds ?

Somehow it works when you use Code Snippets Pro plugin but not when you paste the code in the functions.php file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment