Skip to main content

Why is this Javascript much *slower* than its jQuery equivalent?



I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later):







$('#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));

} );







However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent:







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







To my surprise however, the plain Javascript is up to 10 times slower than the jQuery equivalent. The jQuery version takes around 2-3 seconds to filter on each letter, while the Javascript version takes 17+ seconds! I'm using Google Chrome on Ubuntu Linux.





This isn't for anything really important so it doesn't need to be super efficient. But am I doing something really dumb with my Javascript here?



Source: Tips4all

Comments

  1. You could try using textContent instead of innerText , I think it should be faster. Also timing the list-generation and loop separately would tell if there is problem in list-generation.

    ReplyDelete
  2. Another best practice for javascript speed is caching the list.length in a variable and calling the variable like:

    l = list.length;
    for (var i=0;i<l;i++):{ code here}


    And maybe timing with jsperf would be better.

    ReplyDelete
  3. I used while instead of for and did some minor improvements. Here is the final code.

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

    ReplyDelete

Post a Comment

Popular posts from this blog

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.