不使用被动侦听器来提高滚动性能(灯塔报告)

Posted

技术标签:

【中文标题】不使用被动侦听器来提高滚动性能(灯塔报告)【英文标题】:Does not use passive listeners to improve scrolling performance (Lighthouse Report) 【发布时间】:2020-06-06 23:18:51 【问题描述】:

最近的一份 Lighthouse 报告指出了以下问题。

不使用被动侦听器来提高滚动性能

它还提到...

考虑将您的触摸和滚轮事件侦听器标记为passive,以提高页面的滚动性能。

我该如何解决这个问题?它似乎与jQuery有关。

【问题讨论】:

web.dev/uses-passive-event-listeners 【参考方案1】:

2016年https://github.com/jquery/jquery/issues/2871有一个关于这个话题的长帖

简而言之:

jQuery 无法添加对被动侦听器的支持。 预计会在jQuery 4中加入(4年还在
    5.x)
建议的解决方法是在 jQuery 加载后立即添加此代码:
jQuery.event.special.touchstart = 
        setup: function( _, ns, handle )
            this.addEventListener("touchstart", handle,  passive: true );
        
    ;

2021 年更新:在 jquery 之后添加以下代码。这将修复它并删除 Pagespeed 警告

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 );
    
;

【讨论】:

我在添加 jquery-3.3.1.min.js 的脚本标签之后的脚本标签中添加了这个。灯塔性能仍然不会增加。这里有没有人找到解决方案来真正摆脱报告“不使用被动侦听器来提高滚动性能” 目标是让灯塔报告看起来更适合您的老板/客户,还是让页面实际表现更好? @squarecandy 我认为这两点对很多人来说都是相关的;) 我已经在 jQuery 加载 (v3.2.1) 之后添加了代码,但是 PageSpeed 仍然提到了被动侦听器 @escape-llc 为您的项目添加补丁并进行测试以确保它在该项目上工作比更新(字面上)一半互联网使用的 js 库要简单得多。此答案中链接的来自 jQuery github 的问题线程解释说,一个强大的解决方案将意味着对 .on 进行重大改革,并进行重大更改。【参考方案2】:

这已经成功了!

// Passive event listeners
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 发行版进行了此修复?它会阻止灯塔警告吗? 认为你需要删除!之前的ns.includes 使用 jquery 3.6.0 防止在此评论时出现灯塔警告【参考方案3】:

如何使事件侦听器被动以提高滚动性能。为了解决这个问题-:

    转到主题核心文件。 查找 header.php 或者您可以使用插件将代码插入到标头中。 复制代码并将其粘贴到 header.php 文件中。 如果您打算在 header.php 中使用代码,我强烈建议您使用 PHP 开始和结束标记。

  <script>!function(e)"function"==typeof define&&define.amd?define(e):e()(function()var e,t=["scroll","wheel","touchstart","touchmove","touchenter","touchend","touchleave","mouseout","mouseleave","mouseup","mousedown","mousemove","mouseenter","mousewheel","mouseover"];if(function()var e=!1;tryvar t=Object.defineProperty(,"passive",get:function()e=!0);window.addEventListener("test",null,t),window.removeEventListener("test",null,t)catch(e)return e())var n=EventTarget.prototype.addEventListener;e=n,EventTarget.prototype.addEventListener=function(n,o,r)var i,s="object"==typeof r&&null!==r,u=s?r.capture:r;(r=s?function(e)var t=Object.getOwnPropertyDescriptor(e,"passive");return t&&!0!==t.writable&&void 0===t.set?Object.assign(,e):e(r):).passive=void 0!==(i=r.passive)?i:-1!==t.indexOf(n)&&!0,r.capture=void 0!==u&&u,e.call(this,n,o,r),EventTarget.prototype.addEventListener._original=e);</script>

【讨论】:

以上是关于不使用被动侦听器来提高滚动性能(灯塔报告)的主要内容,如果未能解决你的问题,请参考以下文章

非被动事件侦听器导致“阻塞”代码(使用 React Ace)并因此导致性能问题

向阻止滚动的“touchstart”事件添加了非被动事件侦听器

[Violation] 向 Angular 4 项目中的滚动阻止“touchstart”事件添加非被动事件侦听器是啥意思?

什么是被动事件监听器?

警告:添加非被动事件侦听器到滚动阻塞'touchstart'事件(Added non-passive event listener to a scroll-blocking '

Angular 被动事件监听器