如何限制或限制此函数调用中的函数调用次数(以提高性能)?
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;
};
};
我有一个看起来像这样的函数:
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;
};
};