passive: true 能提升滚动性能,因浏览器跳过对 preventDefault() 的等待,避免 100–300ms 输入延迟;适用于只读滚动、纯视觉 touchmove 等场景,设 passive 后调用 preventDefault() 会被忽略并报错。

在 JavaScript 事件机制中,addEventListener 的 options 参数中设置 passive: true,能显著提升滚动(scroll)、触摸(touchstart、touchmove)等高频事件的响应性能,尤其在移动端。
为什么 passive 能提升滚动性能
浏览器默认会对 touchstart 和 touchmove 事件监听器执行“事件延迟判定”:即等待监听器执行完、确认是否调用了 preventDefault() 后,才决定是否触发默认行为(如页面滚动)。这个等待会造成约 100–300ms 的输入延迟,导致滚动卡顿、不跟手。
将 passive: true 显式声明后,告诉浏览器:“这个监听器**绝不会调用 preventDefault()**”,浏览器就能跳过等待,立即触发默认滚动行为,实现原生级流畅体验。
passive 的典型使用场景
- 只读监听滚动位置:例如监听页面滚动距离做吸顶、懒加载、视差效果
- 纯视觉反馈类 touchmove:比如拖拽滑块但不阻止页面滚动,或记录触摸轨迹用于分析
-
移动端下拉刷新的“非阻断阶段”:下拉未达阈值前允许原生滚动,此时可设 passive;达到阈值后再切换为非 passive 并调用
preventDefault()
正确写法与常见错误
✅ 正确示例(滚动监听):
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
element.addEventListener('scroll', handleScroll, { passive: true });<br>document.addEventListener('touchmove', handleTouchMove, { passive: true });
⚠️ 错误示例(设了 passive 却调用 preventDefault):
element.addEventListener('touchmove', e => {<br> e.preventDefault(); // ❌ 浏览器会忽略该调用,并在控制台报 warning<br>}, { passive: true });
? 若确实需要阻止默认行为(如自定义滚动、手势拦截),必须显式设 passive: false(默认值),或直接省略 options:
element.addEventListener('touchmove', e => {<br> e.preventDefault(); // ✅ 此时生效<br>}); // 等价于 { passive: false }
兼容性与渐进增强建议
passive 在现代浏览器(Chrome 56+、Firefox 49+、Safari 11.1+、Edge 79+)中已全面支持。旧版 Safari 需要加前缀(webkitPassive),但目前已无必要。
推荐做法是用特性检测 + fallback:
const supportsPassive = () => {<br> let supports = false;<br> try {<br> const opts = Object.defineProperty({}, 'passive', {<br> get() { supports = true; }<br> });<br> window.addEventListener('test', null, opts);<br> } catch (e) {}<br> return supports;<br>};<br><br>const options = supportsPassive() ? { passive: true } : false;<br>element.addEventListener('scroll', handler, options);
注意:传 false 作为第三个参数,等价于 { passive: false },不是禁用 options,而是回退到传统冒泡模式。


















