Skip to content

Instantly share code, notes, and snippets.

@sabrina-zeidan
Created September 25, 2021 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sabrina-zeidan/7d34eccceed18421cd49fbd225d156b1 to your computer and use it in GitHub Desktop.
Save sabrina-zeidan/7d34eccceed18421cd49fbd225d156b1 to your computer and use it in GitHub Desktop.
Delay Intercom execution in WordPress
// Intercom plugin adds Intercom script to critical render path, sets it to be not defered
// And adds the script in WordPress in a way it doesn't leave much options to alter it in order to delay Intercom execution and prevent it to be render blocking
// Altering buffer in WP generally in not a great idea, but since we have no choice, let's make sure we are altering it in a way it doesn't break things
// If you use WP Rocket -- use 'rocket_buffer' filter instead
add_action( 'init', 'sz_buffer_process_post' ); //we use 'init' action to use ob_start()
function sz_buffer_process_post() {
ob_start();
}
add_action('shutdown', function() {
$final = '';
$levels = ob_get_level();
for ($i = 0; $i < $levels; $i++) {
$final .= ob_get_contents();
ob_clean();
}
$final_output = apply_filters( 'sz_filter_final_html', $final);
echo $final_output;
}, 0);
// Delay Intercom by varying HTML output via buffer
add_filter( 'sz_filter_final_html', 'sz_filter_html_intercom', 10, 1);
function sz_filter_html_intercom( $html ) {
$current_url = home_url($_SERVER['REQUEST_URI']);
if (!is_admin() && !is_user_logged_in() && (strpos($current_url, 'xmlrpc.php') === false)){
//these checks needed if you are not using WP Rocket buffer
//Main thing is here:
preg_match_all( '/<script.*w\.Intercom=i.*<\/script>/U', $html, $found_scripts ); //in case it is more than one occurences
foreach ( $found_scripts[0] as $found_script ) {
$replace_script = str_replace( 'data-cfasync="false"', 'defer', $found_script ); // defer loading
$replace_script = str_replace( "function l(){", "function l(){ setTimeout(function () {", $replace_script ); //and delay execution
$replace_script = str_replace( 'x.parentNode.insertBefore(s,x);', 'x.parentNode.insertBefore(s,x);}, 3000);', $replace_script );
$html = str_replace( $found_script, $replace_script, $html );
//Many thanks to @wppunk for helping out with this part
}
}
return $html;
}
/**
* There is an alternative to regex -- using DOMDocument -- but mind, the output might be broken if there are errors in $html input
$dom = new DOMDocument;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('script') as $tag) {
if (strpos($tag->nodeValue, "var ic=w.Intercom") !== false) {
$tag->setAttribute('defer', '');
$tag->removeAttribute('data-cfasync');
$tag->nodeValue = str_replace("function l(){", "function l(){ setTimeout(function () {", $tag->nodeValue);
$tag->nodeValue = str_replace('x.parentNode.insertBefore(s,x);', 'x.parentNode.insertBefore(s,x);}, 3000);', $tag->nodeValue);
}
}
$html = $dom->saveHtml();
**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment