【发布时间】:2011-10-24 09:26:05
【问题描述】:
我有一个包含大约 500 个项目的 HTML 列表和一个“过滤器”框。当我输入一个字母时,我开始使用 jQuery 过滤列表(时间代码稍后添加):
$('#filter').keyup( function() {
var jqStart = (new Date).getTime();
var search = $(this).val().toLowerCase();
var $list = $('ul.ablist > li');
$list.each( function() {
if ( $(this).text().toLowerCase().indexOf(search) === -1 )
$(this).hide();
else
$(this).show();
} );
console.log('Time: ' + ((new Date).getTime() - jqStart));
} );
但是,在输入每个字母(尤其是第一个字母)后会有几秒钟的延迟。所以我认为如果我使用纯 Javascript 可能会稍微快一些(我最近读到 jQuery 的 each 函数特别慢)。这是我的 JS 等价物:
document.getElementById('filter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime();
var search = this.value.toLowerCase();
var list = document.querySelectorAll('ul.ablist > li');
for ( var i = 0; i < list.length; i++ )
{
if ( list[i].innerText.toLowerCase().indexOf(search) === -1 )
list[i].style.display = 'none';
else
list[i].style.display = 'block';
}
console.log('Time: ' + ((new Date).getTime() - jsStart));
}, false );
然而,令我惊讶的是,纯 Javascript 比 jQuery 等价物要慢 10 倍。 jQuery 版本过滤每个字母大约需要 2-3 秒,而 Javascript 版本需要 17 多秒!我在 Ubuntu Linux 上使用 Google Chrome。
这不是为了任何真正重要的事情,所以它不需要超级高效。但是我在这里用我的 Javascript 做的事情真的很愚蠢吗?
【问题讨论】:
-
我会为这两个选择器计时,看看是不是全部都在那里;我知道 jQuery 选择器的东西已经被调到死了。
-
缓存
list.length是一回事,尽管它不会产生如此大的差异。据说你的计时方法也不准确。 ejohn.org/blog/accuracy-of-javascript-time -
@Dave:jQuery 倾向于尽可能多地使用浏览器的原生选择器支持,基本上任何不是 jQuery 特定的选择器都应该由浏览器的原生界面处理,因为它会显着比用 JavaScript 更快。
-
@DaveNewton querySelectorAll = 1 毫秒,$() = 3 毫秒。绝对不是选择器!
-
尝试用
textContent代替innerText看看是否有区别。此外,您是否有理由在每个 keyup 事件上运行'ul.ablist > li'?预计会改变吗?如果是这样,我会使用实时 NodeList。无论哪种方式,我都会将其缓存在处理程序之外。
标签: javascript jquery performance