Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个Javascript比它的jQuery等价物慢得多?_Javascript_Jquery_Performance - Fatal编程技术网

为什么这个Javascript比它的jQuery等价物慢得多?

为什么这个Javascript比它的jQuery等价物慢得多?,javascript,jquery,performance,Javascript,Jquery,Performance,我有一个大约500个项目的HTML列表,上面有一个“过滤器”框。当我键入一封信时,我首先使用jQuery过滤列表(稍后添加计时代码): 但是,在输入每个字母(尤其是第一个字母)后,会有几秒钟的延迟。所以我认为如果我使用纯Javascript(我最近读到jQuery的每个函数都特别慢),速度可能会稍微快一点。以下是我的JS等价物: document.getElementById('filter').addEventListener( 'keyup', function () { var j

我有一个大约500个项目的HTML列表,上面有一个“过滤器”框。当我键入一封信时,我首先使用jQuery过滤列表(稍后添加计时代码):

但是,在输入每个字母(尤其是第一个字母)后,会有几秒钟的延迟。所以我认为如果我使用纯Javascript(我最近读到jQuery的
每个
函数都特别慢),速度可能会稍微快一点。以下是我的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。无论如何,我都会将其缓存在处理程序之外。谢谢,using
textContent
完全解决了这个问题-过滤现在是即时的!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 );