Consider marking event handler as 'passive' to make the page more responsive

JavascriptJqueryAngularjsTouchhammer.js

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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 fairly recently (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: https://stackoverflow.com/questions/37721782/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:

Solution 2 - Javascript

This hides the warning message:

jQuery.event.special.touchstart = {
  setup: function( _, ns, handle ) {
	  this.addEventListener("touchstart", handle, { passive: !ns.includes("noPreventDefault") });
  }
};

Solution 3 - Javascript

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.

Solution 4 - Javascript

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

Solution 5 - Javascript

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

Solution 6 - Javascript

Also encounter this in select2 dropdown plugin in Laravel. Changing the value as suggested by Alfred Wallace from

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

to

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

solves the issue. Why he has a down vote, I don't know but it works for me.

Solution 7 - Javascript

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

Solution 8 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - JavascriptAnson KaoView Answer on Stackoverflow
Solution 2 - JavascriptIván RodríguezView Answer on Stackoverflow
Solution 3 - JavascriptShanaka RathnayakaView Answer on Stackoverflow
Solution 4 - JavascriptAlfred WallaceView Answer on Stackoverflow
Solution 5 - JavascriptAndreyPView Answer on Stackoverflow
Solution 6 - JavascriptJun SalenView Answer on Stackoverflow
Solution 7 - JavascriptRiad N HaddadView Answer on Stackoverflow
Solution 8 - JavascriptMark LancasterView Answer on Stackoverflow