首页 > 解决方案 > 同一窗口事件的多个侦听器如何影响性能?

问题描述

在一个 Web 项目中,我为同一个窗口事件使用多个侦听器。

window.addevntlistener("resize", callback)
window.addevntlistener("hasChange", callback)

我假设在窗口上添加多个事件侦听器对性能的影响可以忽略不计。是这样,还是我应该只听一次,然后为需要通知的各个单元添加我自己的 javascript 订阅解决方案?

调整大小的侦听器可以由呈现在列表中的基本 UI 元素使用,因此可以添加数百个侦听器。

编辑: 我知道添加太多事件侦听器会影响性能吗?. 但是,那是指一个元素的点击事件。在这种情况下,多个对象有多个侦听器。在我的例子中,同一个对象有多个监听器,还有一个特殊的对象——窗口。

标签: javascriptbrowser

解决方案


在 Javascript 中,您有一个事件循环。该机制由一个循环组成,它表示按给定顺序调用某些函数的计划。但是,用户事件(例如单击或调整大小)无法在发生之前进行计划。因此,还有一个消息队列(也称为回调队列),您的事件正在等待执行。

在此处输入图像描述

当事件队列用完要执行的函数时,消息队列的项目开始被处理。此时您的事件将被处理。

基本上我们谈论的是一个永远循环,你可以在其中放置一些函数。当然它会影响性能,因为与未完成的情况相比,要完成的所有事情都会影响性能。但是,在大多数情况下,这并不意味着可以感觉到任何有意义的差异。

如果我们假设您与这些事件相关联的函数的复杂度非常低(可能是恒定的),那么由于事件循环,我们仍然具有线性复杂度,您必须向该循环添加许多事件才能获得任何性能差异可以感觉到。

但是,如果您添加的函数非常复杂,则会显着降低性能,请注意,Javascript(大部分)是单线程的。因此,如果您遇到性能问题,那么您需要首先检查您的功能的复杂性。

值得注意的是,您的事件处理程序只会在给定事件被触发时执行,可能是由用户触发的。因此,如果您添加一百万个调整大小处理程序,它们本身不会影响性能(添加时除外,但这无关紧要),但是当调整大小发生时,将执行附加到此事件的所有事件处理程序.

因此,如果您在给定事件中遇到性能问题,那么您将需要分析与该事件关联的事件处理程序。如果您的事件处理程序太多或太复杂,那么您可以使用Web Worker(它们在单独的线程中运行)来执行更耗时的作业,因此您的 UI 在处理事件方面将保持响应。

编辑

这就是测试这两种情况的方法。在这段代码中,我们假设它event是一个String变量,可以是点击、按键事件或任何东西。

测量功能

var count = 1000; //you can change this value whenever you need
var startDate;
var endDate;
var diff;

function happened() {
    if (!startDate) startDate = performance.now();
    if (!(--count)) {
        endDate = performance.now();
        diff = endDate - startDate; //in milliseconds
        console.log(diff);
    }
}

许多听众

for (var i = 0; i < count; i++) window.addEventListener("resize", function() {happened()});

我的测试用了 61 毫秒(在我的情况下,事件是“调整大小”)

单听者

window.addEventListener("resize", function() {
    while (count > 0) happened();
});

我的测试用了 55 毫秒(在我的情况下,事件是“调整大小”)


推荐阅读