如何限制或限制此函数调用中的函数调用次数(以提高性能)?

How to limit or throttle the number of function calls (in order to increase performance) in this function call?

我有一个看起来像这样的函数:

function someFunction(text) {
    $('.class').each(function() {
        var $this = $(this);
        if ($this.text().match(text)) {
           $this.addClass('found');
        } else {
           $this.removeClass('found');
        }
    });
}

并且该函数在 keyup 事件中执行,

$('input[type=text]').keyup(function() {
   someFunction($(this).val());
});

在 IE 上,如果有很多 .class 元素,它可能会很慢,我认为如果我停止执行每个调用,如果函数在每个调用完成之前再次执行,我可以加快速度。我该怎么做?

您可以通过向 keyup 处理程序添加轻微的延迟来加快此过程,这样 DOM 仅在键入结束后而不是每次击键时受到影响。您还可以使用 :contains 选择器来查找元素。试试这个:

function someFunction(text) {
    $('.class').removeClass('found').filter(':contains("' + text + '")').addClass('found');
}

var timer;
$('input[type=text]').keyup(function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
        someFunction(this.value);
    }, 100);
});

此外,如@A.Wolff 所述,您可以缓存 .class 选择器,但这仅在没有 .class 元素动态添加到 DOM 时才有效当您搜索时:

var $elements = $('.class');
function someFunction(text) {
    $elements.removeClass('found').filter(':contains("' + text + '")').addClass('found');
}

var timer;
$('input[type=text]').keyup(function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
        someFunction(this.value);
    }, 100);
});

尝试在函数末尾添加 return false;

function someFunction(text) {
    $('.class').each(function() {
        var $this = $(this);
        if ($this.text().match(text)) {
           $this.addClass('found');
        } else {
           $this.removeClass('found');
        }

    });
    return false;
}

由于我误解了问题,这里有两个优化(两者可以一起使用):

缓存查询结果,只是偶尔通过定时器更新

不是很漂亮,但考虑到性能提升至关重要,可能会提供一个可靠的解决方案。

window.lastValue = null;

window.cachedElements = null;

window.updateCachedElements = function(){ cachedElements = $('.class'); };

function someFunction() {
    cachedElements.each(function() {
        var $this = $(this);
        if ($this.text().match(lastValue)) {
           $this.addClass('found');
        } else {
           $this.removeClass('found');
        }
    });
}

$('input[type=text]').keyup(function() {
    if(cachedElements === null) {
        updateCachedElements();
    }

    lastValue = $(this).val()

    someFunction();
});

setInterval(function(){ updateCachedElements(); someFunction(); }, 500);

使用去抖动(一种节流形式)将 someFunction 调用次数降至每秒 1/100 毫秒或 10 次

someFunction 定义之后(和 之外),执行:

someFunction = debounce(someFunction, 100);

来自 underscore.js 的去抖实现:

_.debounce = function(func, wait, immediate) {
    var timeout, args, context, timestamp, result;

    var later = function() {
        var last = (Date.now || new Date().getTime()) - timestamp;

        if (last < wait && last >= 0) {
            timeout = setTimeout(later, wait - last);
        } else {
            timeout = null;
            if (!immediate) {
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            }
        }
    };

    return function() {
        context = this;
        args = arguments;
        timestamp = _.now();
        var callNow = immediate && !timeout;
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(context, args);
            context = args = null;
        }

        return result;
    };
};