How Passive Touch Event Listeners Boost Mobile Scrolling Performance in Chrome
This article explains why touch event handlers can degrade mobile scrolling, how Chrome's passive listener option improves performance by default, the implementation details, common pitfalls, and practical fixes using CSS touch-action and proper event handling.
1. Introduction
Scrolling is a crucial interaction for mobile web pages, but touch event handlers often cause serious performance problems. Chrome allows developers to pass {passive: true} to addEventListener(), making listeners passive so they no longer block scrolling.
Starting with Chrome 56, touch listeners are passive by default, which greatly improves user experience without significant impact on sites.
In rare cases this can cause unintended scrolling; adding the CSS property touch-action: none to the affected element prevents scrolling.
2. Background
If you call preventDefault() inside touchstart or touchmove handlers, the page scroll is blocked. Browsers must wait for the handler to finish before deciding whether to scroll. By registering listeners with {passive: true}, the browser assumes preventDefault() will not be called, allowing smooth scrolling. Example:
element.addEventListener('touchstart', handler, {passive: true});3. Optimization
The goal is to reduce latency after a touch. Observations show about 80% of listeners are already passive but not registered as such. Chrome now defaults passive: true for listeners attached to window, document, or body.
Implementation (illustrated in the image) sets passive to true for these listeners.
Now calls to preventDefault() inside handlers are ignored.
Performance data collected on Android Chrome shows average latency dropping from over 400 ms to about 250 ms—a 38% reduction—with a target of sub‑50 ms response time.
4. Issues and Fixes
In most cases the optimization does not introduce bugs, but occasional unwanted scrolling or unexpected click events may occur. In Chrome 56+ a DevTools warning is printed if preventDefault() is called on a passive listener.
You can check the defaultPrevented property to see whether preventDefault() took effect.
Most problems are easily fixed by using the CSS touch-action property, e.g., touch-action: none to prevent any scrolling or zooming, or touch-action: pan-y pinch-zoom to allow only vertical scrolling and pinch‑zoom.
Because Safari and some older browsers do not support touch-action, you still need to call preventDefault() in event handlers for those environments.
If preventDefault() is called in a touchstart listener to block a click, ensure it is also called in the corresponding touchend listener.
If you must override the default and need a non‑passive listener, pass {passive: false} to addEventListener() and verify that the browser supports EventListenerOptions.
5. Conclusion
After Chrome 56’s passive‑listener optimization, most pages scroll faster, though a few may exhibit unexpected scrolling. Developers should avoid calling preventDefault() in touchstart or touchmove handlers and instead use the touch-action CSS property to control scrolling and zooming, reserving preventDefault() for touchend only when necessary.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
