Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WordPress: Move inline JS to be fired after deffered jQuery

Trying to follow Google Page Insights suggestions, I've got the "JS render block" recommendation for and it is related to jQuery main file.

My site use WordPress with some plugins. One of the plugins throw its JS inline. So when I move jQuery to load in the footer, or when I use "defer" mode to load it, I get jQuery is not defined once the inline code fired.

I was trying to find a global solution to 'catch' all inline scripts and delay it after jQuery main file is executed at the end of the document.

I wrote a solution that works great for me. It is very straight forward solution for my specific situation, but I failed to make this as a filter for the_content or widget output. I would like to make this a global solution, so I wouldn't need to worry about any JS firing somewhere.

Any ideas how to make it work? Here my code so far, for this specific case, which runs through a shortcode:

/* Get shortcode HTML */ 
$widget_shortcode = do_shortcode($shortcode);

/* Take out all scripts into an array */
$delayed_scripts = array();
preg_match_all('#<script(.*?)</script>#is', $widget_shortcode, $match);
foreach ($match as $val){
    $delayed_script = '<script '.$val[0].'</script>';
    array_push($delayed_scripts, $delayed_script);
}

/* Remove all scripts from HTML */
$widget_shortcode = preg_replace('#<script(.*?)</script>#is', '', $widget_shortcode);

/* Echo filtered HTML */
echo $widget_shortcode;

And just before the closing </body> tag:

foreach ($delayed_scripts as $script) {
    echo $delayed_script;
}
like image 911
Shir Gans Avatar asked Nov 09 '22 12:11

Shir Gans


1 Answers

I have worked very hard with this same issue. There are a few things to consider here. This problem would be easy if every plugin enqueued scripts in Wordpress properly, unfortunately, many do not and instead just echo the script or use a standard include.

As some commenters have noted if you want to catch all inline scripts you have no choice but to search the output buffer for script tags because if a plugin echoes a script there is nothing you can do in WordPress after that as it is sent to the buffer.

Keep in mind, using preg statements and searching entire html docs and then manipulating strings is probably much more expensive than letting jQuery load in the head. That will increase the server response time for the html doc and this wait time is just as bad because it is also time were no rendering is happening and the user is sitting there with a blank screen. Not to mention, moving jQuery to footer means anything that depends on it will not work until the footer is parsed. This is the same reason Google recommends putting analytics code in the head. What if a user navigates away before the analytics code had a chance to parse?

Google Page speed is a guide, not a rule. Don't bang your head against a wall trying to get a perfect score.

like image 82
gunnerman Avatar answered Nov 15 '22 10:11

gunnerman