In 2017, Chrome, Firefox and Safari added support for passive event listeners. They help to make scrolling work smoother and are enabled by passing {passive: true}
into addEventListener()
.
The explainer mentions that passive: true
works for wheel and touch events. I practically analyzed when passive: true
actually helps:
Event | Works better with passive: true |
Is passive by default |
---|---|---|
wheel ¹ |
Yes (Chrome), No (Firefox) | No (Chrome), No (Firefox) |
touchstart |
Yes (Chrome), ?² (Firefox) | Yes (Chrome), ?² (Firefox) |
touchmove |
Yes (Chrome), ?² (Firefox) | Yes (Chrome), ?² (Firefox) |
touchend |
No (Chrome), ?² (Firefox) | (Not applicable) |
resize |
No (Chrome, Firefox) | (Not applicable) |
mousemove |
No (Chrome, Firefox) | (Not applicable) |
keydown |
No (Chrome, Firefox) | (Not applicable) |
scroll |
No³ (Chrome, Firefox) | (Not applicable) |
(Testing was performed in Chrome 62.0.3168.0 Canary and Firefox 55.0b12 Developer Edition.)
Notes:
-
This is related both to
wheel
andmousewheel
events (mousewheel
is deprecated in favor ifwheel
). However, Firefox triggers only thewheel
events (so you can’t catch or make passive themousewheel
event listener). -
I was unable to catch
touch*
events on Firefox with my device (instead, touch scrolling triggeredwheel
events). Probably I’ll try later with another device and update this table. -
The
scroll
event is a weirdo. Unlike other events, it can be triggered in multiple ways (touch scrolling, keyboard scrolling, dragging the scrollbar, scrolling the mouse wheel), and, depending on the way it’s triggered, it either gets blocked by a long listener or not. Moreover, this differs across the browsers. But, generally, adding{ passive: true }
to the scroll event listener seems to do nothing.
Resources:
- The codepen I used for testing
- The Rick Byers’ playground for testing page junk
Follow me on Twitter: @iamakulov
You can tell that
passive
does nothing onscroll
events because they are notcancelable
, i.e.preventDefault()
on them does nothing.