解决 PageSpeed Insights “未使用被动式监听器来提高滚动性能” 警告

在使用 PageSpeed Insights 测试我们的 WordPress 站点的使用,如果前端加载了 jQuery 库,我们往往会收到一条「未使用被动式监听器来提高滚动性能」的警告,谷歌建议我们将触摸和滚轮事件监听器标记为 `passive`,以提高页面的滚动性能

为什么出现未使用被动式监听器的警告

在浏览器渲染网页的过程中,默认情况下,浏览器会主动监听绑定到触摸和滚动事件,根据该事件的运行结果和是否阻止浏览器的默认行为来判断是否执行默认操作。比如我们可以在 touchstart 事件调用 preventDefault ,这时,浏览器会禁用该事件的默认操作,不会滚动或缩放。

而浏览器无法预先知道一个监听器会不会调用 preventDefault(),它需要等监听器执行完后,再去执行默认行为,而监听器执行是要耗时的,这样就会导致页面卡顿。更深入的解释参考:移动Web滚动性能优化: Passive event listeners。

让WordPress内置的jQuery使用被动式监听器的办法

如果我们把监听器的监听方式改为被动的,就可以消除掉这个延时,提高网页的触摸和滚动性能。虽然这个警告不会直接影响PageSpeed Insights的评分,解决掉这个延时后,对提高网页的用户体验还是有一些帮助的。

截止本文发布之日,WordPress内置的jQuery尚不支持这个操作。很幸运的是,我们可以通过一段简单的代码来为jQuery加上这个支持。

add_action('wp_enqueue_scripts', function ()
{
wp_add_inline_script('jquery', '
jQuery.event.special.touchstart = {
setup: function( _, ns, handle ) {
this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
}
};
jQuery.event.special.touchmove = {
setup: function( _, ns, handle ) {
this.addEventListener("touchmove", handle, { passive: !ns.includes("noPreventDefault") });
}
};
jQuery.event.special.wheel = {
setup: function( _, ns, handle ){
this.addEventListener("wheel", handle, { passive: true });
}
};
jQuery.event.special.mousewheel = {
setup: function( _, ns, handle ){
this.addEventListener("mousewheel", handle, { passive: true });
}
};'
);
}, 999);

如果您的网站中没有使用jQuery,依然出现了未使用被动式监听器来提高滚动性能的警告,可以参考以上代码中的this.addEventListener 部分修改您的代码,来实现被动式监听。