为什么这个Javascript比它的jQuery等价物慢得多?
我有一个大约500个项目的HTML列表,上面有一个“过滤器”框。当我键入一封信时,我首先使用jQuery过滤列表(稍后添加计时代码): 但是,在输入每个字母(尤其是第一个字母)后,会有几秒钟的延迟。所以我认为如果我使用纯Javascript(我最近读到jQuery的为什么这个Javascript比它的jQuery等价物慢得多?,javascript,jquery,performance,Javascript,Jquery,Performance,我有一个大约500个项目的HTML列表,上面有一个“过滤器”框。当我键入一封信时,我首先使用jQuery过滤列表(稍后添加计时代码): 但是,在输入每个字母(尤其是第一个字母)后,会有几秒钟的延迟。所以我认为如果我使用纯Javascript(我最近读到jQuery的每个函数都特别慢),速度可能会稍微快一点。以下是我的JS等价物: document.getElementById('filter').addEventListener( 'keyup', function () { var j
每个函数都特别慢),速度可能会稍微快一点。以下是我的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 );
document.getElementById('filter').addEventListener('keyup',function(){
var jsStart=(新日期).getTime();
var search=this.value.toLowerCase();
var list=document.querySelectorAll('ul.ablist>li');
对于(变量i=0;i
然而,令我惊讶的是,普通Javascript的速度比同等的jQuery慢10倍。jQuery版本需要大约2-3秒来过滤每个字母,而Javascript版本需要17秒以上!我在Ubuntu Linux上使用Google Chrome
这不是为了任何真正重要的事情,所以它不需要超级高效。但是我在这里用Javascript做的事情真的很愚蠢吗?你可以尝试使用textContent
而不是innerText
,我认为应该更快。另外,分别对列表生成和循环计时也可以判断列表生成中是否存在问题。另一种提高javascript速度的最佳做法是在变量中缓存list.length
,并调用变量,如下所示:
l = list.length;
for (var i=0;i<l;i++):{ code here}
l=list.length;
对于(var i=0;i我使用了而不是作为,并做了一些小的改进。这是最终的代码
var list = list = document.querySelectorAll('ul.ablist > li');
document.getElementById('javascriptFilter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime(),
search = this.value.toLowerCase(),
i = list.length - 1,
listItem,
result;
while( i >= 0 )
{
listItem = list[i];
if ( listItem.textContent.toLowerCase().indexOf(search) === -1 )
listItem.style.display = 'none';
else
listItem.style.display = 'block';
i--;
}
result = ((new Date).getTime() - jsStart);
console.log(['Time: ', result, '<br />'].join(''));
}, false );
var list=list=document.queryselectoral('ul.ablist>li');
document.getElementById('javascriptFilter').addEventListener('keyup',function(){
var jsStart=(新日期).getTime(),
search=this.value.toLowerCase(),
i=列表长度-1,
列表项,
结果;
而(i>=0)
{
listItem=列表[i];
如果(listItem.textContent.toLowerCase().indexOf(搜索)=-1)
listItem.style.display='none';
其他的
listItem.style.display='block';
我--;
}
结果=((新日期).getTime()-jsStart);
console.log(['Time:',result'
'].join('');
},假);
在这里,我对您的代码进行了一些重构:
var filter = document.getElementById( 'filter' ),
ablist = document.querySelector( '.ablist' );
filter.addEventListener( 'keyup', function () {
var re, elems, i, len, elem;
re = RegExp( this.value, 'i' );
elems = ablist.children;
for ( i = 0, len = elems.length; i < len; i += 1 ) {
elem = elems[i];
elem.style.display =
elem.textContent.search( re ) > -1 ? 'list-item' : 'none';
}
}, false );
var filter=document.getElementById('filter'),
ablist=document.querySelector('.ablist');
filter.addEventListener('keyup',function(){
变量re,elems,i,len,elem;
re=RegExp(this.value'i');
elems=一组儿童;
对于(i=0,len=elems.length;i-1“列表项”:“无”;
}
},假);
现场演示:
变化:
- 有了正则表达式和
i
标志,就不需要toLowerCase
- 如果页面上只有一个
'.ablist'
元素,querySelector
应该是获取该元素的最快方法(因为一旦找到第一个这样的元素,它就会中止查询)
- 没有对li元素的查询,因为
子属性已经方便地引用了它们
我很想知道这段代码在您的页面上的执行情况…我会对两个选择器计时,看看它们是否都在那里;我知道jQuery选择器的东西已经被调整到了死角。缓存list.length
是一回事,尽管它不会造成这么大的差异。而且据说您的计时方法不准确。@Dave:jQuery要尽可能多地使用浏览器的本机选择器支持,基本上任何不是特定于jQuery的选择器都应该由浏览器的本机接口来处理,因为它比在JavaScript中处理要快得多。@DaveNewton querySelectorAll=1ms,$()=3ms。绝对不是选择器!尝试用textContent
替换innerText
,看看它是否有区别。另外,您在每个keyup事件上运行'ul.ablist>li'
有什么原因吗?它是否会更改?如果是,我会使用一个live NodeList。无论如何,我都会将其缓存在处理程序之外。谢谢,usingtextContent
完全解决了这个问题-过滤现在是即时的!17000毫秒降到~8ms:D+1=10。这是一个青铜徽章;)@不满意的额外信息:((新日期)。getTime-jsStart)
的外部逗号不是严格必要的,因为JavaScript表达式是从右到左计算的。另见:@RobW获得了徽章。干杯
var filter = document.getElementById( 'filter' ),
ablist = document.querySelector( '.ablist' );
filter.addEventListener( 'keyup', function () {
var re, elems, i, len, elem;
re = RegExp( this.value, 'i' );
elems = ablist.children;
for ( i = 0, len = elems.length; i < len; i += 1 ) {
elem = elems[i];
elem.style.display =
elem.textContent.search( re ) > -1 ? 'list-item' : 'none';
}
}, false );