287

I am using hammer for dragging and it is getting choppy when loading other stuff, as this warning message is telling me.

Handling of 'touchstart' input event was delayed for X ms due to main thread being busy. Consider marking event handler as 'passive' to make the page more responsive.

So I tried to add 'passive' to the listener like so

Hammer(element[0]).on("touchstart", function(ev) {
  // stuff
}, {
  passive: true
});

but I'm still getting this warning.

0

8 Answers 8

315

For those receiving this warning for the first time, it is due to a bleeding edge feature called Passive Event Listeners that has been implemented in browsers over the summer 2016. From https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md:

Passive event listeners are a new feature in the DOM spec that enable developers to opt-in to better scroll performance by eliminating the need for scrolling to block on touch and wheel event listeners. Developers can annotate touch and wheel listeners with {passive: true} to indicate that they will never invoke preventDefault. This feature shipped in Chrome 51, Firefox 49 and landed in WebKit. For full official explanation read more here.

See also: What are passive event listeners?

You may have to wait for your .js library to implement support.

If you are handling events indirectly via a JavaScript library, you may be at the mercy of that particular library's support for the feature. As of December 2019, it does not look like any of the major libraries have implemented support. Some examples:

13
  • 21
    what about ionic libraries?
    – abhit
    Commented Dec 15, 2016 at 10:17
  • 14
    I am calling preventDefault() - Is it possible to suppress this warning?
    – maja
    Commented May 29, 2017 at 6:51
  • 2
    @maja no - stackoverflow.com/questions/44060131/…
    – Zze
    Commented Jun 9, 2017 at 0:47
  • 23
    Google Maps JavaScript API version 3 also generates these warnings. Issue is being tracked at issuetracker.google.com/issues/63211698. (Kind of ironic, considering that Google Chrome is warning about violations that Google Maps JavaScript API generates.) Commented Aug 2, 2017 at 7:41
  • 13
    to suppress this warning you can ` addEventListener('touchstart', this.callPassedFuntion, { passive: false })` Commented Jun 13, 2018 at 8:07
31

The following library resolved the issue.
Simply add this code to your project.

<script type="text/javascript" src="https://unpkg.com/default-passive-events"></script>

If you need more information visit this library.

1
  • After using your fix - autocomplete of jQuery loses it's ability to select an item with a mouse. Keyvoard works but still not a good side effect.
    – user1034461
    Commented May 11 at 15:18
17

This hides the warning message:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ) {
      this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
  }
};
4
  • 12
    Wouldnt the goal to be to stop the actual event? I wouldn't want to hide the message until I have handled the issue. Commented Feb 27, 2019 at 16:06
  • 1
    I think it is a jquery library issue. I think developers will must fix it. But if you will get it, let me know how to do it please. Thank you so much. Commented Feb 27, 2019 at 18:23
  • For sure Ivan! Yes it is. Hey, now I am curious... I am using d3 plugin and I am getting like 2300 violations. Maybe your code will help! I will keep you posted! Commented Feb 27, 2019 at 19:03
  • 2
    @yardpenalty.com, no, stopping the event is not the goal! The warning states you have placed your listener without specifying whether it might or might not prevent default behavior on the event. If you have cases where you want to call preventDefault(), you should specify passive: false. If not, specify passive: true. You only get the warning if you don't specify either. If you specify passive: true and preventDefault() gets called, it results in an error and default is not prevented. Specifying passive is not a hack here. It's the solution. It's what the warning asks for!
    – tao
    Commented Apr 18, 2020 at 3:13
9

For jquery-ui-dragable with jquery-ui-touch-punch I fixed it similar to Iván Rodríguez, but with one more event override for touchmove:

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') });
    }
};
0
8

For those stuck with legacy issues, find the line throwing the error and add {passive: true} - eg:

this.element.addEventListener(t, e, !1)

becomes

this.element.addEventListener(t, e, { passive: true} )
7

The warning is only issued if you don't specify passive.

To suppress this warning you can:

addEventListener('touchstart', this.callPassedFuntion, { 
  passive: false 
})

By default, the browser listens for preventDefault. So, it will listen, but it will let you know: hey, you could improve your app here. If not, let me know you can't (by stating: passive: false).

I've created this answer from the comments of the accepted answer, which could be harder to find for anyone trying to find this.

3

I think in addition to touch-based events you can add scroll-based fixes so to prevent google page score from flagging it for Desktop vs Mobile:

// Passive event listeners (Tw0 slight variations in setting the flag)

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

I found a solution that works on jQuery 3.4.1 slim

After un-minifying, add {passive: true} to the addEventListener function on line 1567 like so:

t.addEventListener(p, a, {passive: true}))

Nothing breaks and lighthouse audits don't complain about the listeners.

3
  • 8
    never change the source code of a library; you should override it instead.
    – Raptor
    Commented Apr 21, 2020 at 8:45
  • How do you implement the override to a event listener in jquery?
    – AugustoM
    Commented Aug 20, 2020 at 8:35
  • Right, definitely agree not to change the library... just saying it's a solution Commented Dec 11, 2020 at 19:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.