Does not use passive listeners -SOLVED-

If like 1/2 the internet you are using WordPress for CMS, you might have noticed this issue. If you try to run a speed test with Google, it will most likely flag a red error saying “Does not use passive listeners to improve scrolling performance”. That is bad for your score.

As a personal challenge I wanted to get in the green zone with the test, and was recently successful thanks to this fix.

The issue

As described in the official ticketing system for WordPress, as of the day of this article publishing there is an ongoing issue with a core script in WordPress (js/comment-reply.min.js) generating “non-passive” listeners. The script is responsible for comments UI features, in specific enabling users to comment in reply to another comment (i.e. nested commenting).

The problem with “non-passive” listeners is that they can slow down simple user interactions such as scrolling.

If you don’t allow nested comments anyway, you could simply remove this script from loading.

The error message on Google's 'Page Speed insights'

The fix

The idea is to avoid loading the problematic script by default, and then setting a listener to load it in case it is actually required.

Remove the script

-Edited- Aug-3rd, 2021: Code edited to prevent user having to click ‘reply’ twice.

In your functions.php file, add the following:

function wp_dereg_script_comment_reply(){wp_deregister_script( 'comment-reply' );}
add_action('init','wp_dereg_script_comment_reply');

add_action('wp_head', 'wp_reload_script_comment_reply');
function wp_reload_script_comment_reply() {
    ?>
<script>
//Function checks if a given script is already loaded
function isScriptLoaded(src){
    return document.querySelector('script[src="' + src + '"]') ? true : false;
}
//When a reply link is clicked, check if reply-script is loaded. If not, load it and emulate the click
var repLinks = document.getElementsByClassName("comment-reply-link");
for (var i=0; i < repLinks.length; i++) {
    repLinks[i].onclick = function() { 
    if(!(isScriptLoaded("/wp-includes/js/comment-reply.min.js"))){
        var script = document.createElement('script');
        script.src = "/wp-includes/js/comment-reply.min.js";
    script.onload = emRepClick(event.target.getAttribute('data-commentid'));        
        document.head.appendChild(script);
    }
}
};
//Function waits 50 ms before it emulates a click on the relevant reply link now that the reply script is loaded
function emRepClick(comId) {
sleep(50).then(() => {
document.querySelectorAll('[data-commentid="'+comId+'"]')[0].dispatchEvent(new Event('click'));
});
}
//Function does nothing, for a given amount of time
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}
</script>
    <?php
}

Final thoughts

Hopefully this core issue will be fixed in future WordPress versions and this solution will no longer be required. This solution assumes use of jQuery. It is worth mentioning that “non-passive” listeners can be generated by plugins installed on your CMS. This guide only explains how to solve the issue generated by the core CMS, not any additional plugins.

You can see a demo here: Make my Sushi.

Please comment if you tried it or have any thoughts or ideas around it.

Update – This post is starting to gain popularity. That must mean the solution is useful to some people.

If you got here from a social post, I’d appreciate if you can mention in the comments where you saw it so I can reach out there with questions etc.