Home Ask Login Register

Developers Planet

Your answer is one click away!

jcubic February 2016

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

I have a function that look like this:

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

and that function is executed in keyup event,

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

on IE if there are lot of .class elements it can be slow, I thought that I could speed things up if I stop executing the each call if the function have been executed again before each is finished. How can I do this?

Answers


Rory McCrossan February 2016

You could speed this up by adding a slight delay to the keyup handler so that the DOM is only affected after typing has ended instead of on each keystroke. You can also use the :contains selector to find the elements. Try this:

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);
});

Also, as mentioned by @A.Wolff you could cache the .class selector, but this would only work if no .class elements are dynamically added to the DOM while you're searching:

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);
});


Erkan Özkök February 2016

Try adding return false; end of your function

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

    });
    return false;
}


Björn Ali Göransson February 2016

As I misunderstood the question, here're two optimizations instead (both can be used together):

Cache the query result, only occasionally updating it by timer

Not really beautiful but may provide a robust solution given that the performance gain is critical.

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);

Use debounce (a form of throttling) to minimize number of someFunction calls to 1/100ms or 10 per second

After (and outside) the someFunction definition, do:

someFunction = debounce(someFunction, 100);

Debounce implementation from 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 = imme 

Post Status

Asked in February 2016
Viewed 1,980 times
Voted 14
Answered 3 times

Search




Leave an answer


Quote of the day: live life