使用被动事件监听器加速滚动事件
好吧,让我快速把这个问题说清楚。我讨厌wheel
那些将事件touchstart
附加到页面的网站touchmove
。非常讨厌它们。主要原因是它们的性能太差,尤其是在移动设备上。你看,浏览器必须等到事件监听器完成执行后才能重新绘制页面,因为事件可以被取消。如果你的事件在每次滚动时都运行,那么滚动页面就会变得非常不顺畅,特别是如果你没有对事件进行反跳。幸运的是,现在有一个解决方案:被动事件监听器。
被动事件监听器允许您将不可取消的处理程序附加到事件,让浏览器围绕事件侦听器进行优化。例如,浏览器可以继续以本机速度滚动,而无需等待事件处理程序完成执行。
虽然它们是规范中相对较新的成员,但它们已经得到了大多数大公司的支持。(基本上,除了 IE、Edge 和 Opera Mini 之外的所有公司。)
此外,它们的使用方式不会真正破坏现有行为。如果您需要支持其他浏览器,可以使用此polyfill。
用法
不幸的是,使用被动事件非常复杂。
假设你的原始代码是这样的:
// Really, if you're using wheel, you should instead be using the 'scroll' event, as it's passive by default.
document.addEventListener('wheel', (evt) => {
// ... do stuff with evt
}, true)
您需要将其替换为:
document.addEventListener('wheel', (evt) => {
// ... do stuff with evt
}, {
capture: true,
passive: true
})
是的。我知道。几乎无法理解。?
让我尝试解释一下。
因此,通常在注册滚动事件时,您会添加最后一个参数,true
以指示您的事件应在捕获阶段运行。(即从上到下而不是从下到上)
启用被动事件的新功能之一是事件监听器选项规范。听起来很吓人,但实际上它只是可选地用具有一些属性的对象替换捕获布尔值。在这种情况下,我们可以设置capture
为true
以获得与第一个例子相同的结果,然后设置passive
为true
使事件被动。
为了进一步提高性能,请确保您对事件进行限制或去抖动。
用途
在移动设备上,性能损失最大的事件(比如说,速度快了 5 倍)是滚动,车轮,触摸启动, 和触摸移动。默认情况下,滚动已经是被动的,因此这消除了一个事件。从 Chrome 55 开始,触摸启动和触摸结束也是被动的。
因此,如果您在移动设备上处理这四个事件中的任何一个,那么添加这个微小的 polyfill 并添加{ passive: true }
到这些事件中不会有什么坏处。99% 的时间您都不需要取消这些事件,而且使用{ passive: true }
可以大大提高性能。那么为什么不呢?