Можно ли оптимизировать поиск на стороне клиента в Javascript? - PullRequest
3 голосов
/ 12 января 2012

Вот код jQuery / Javascript, который я использую для сортировки неупорядоченного списка элементов и удаления их по запросу пользователя:

// event binding for the search filter
$('.search-box').keyup(function(){
    var query = $(this).val().toLowerCase(),
        length = query.length;

    $('.friends-list li').each(function(){
        if(query.length > 1 && $(this).find('span').text().toLowerCase().substring(0, length) != query){
            $(this).hide();
        } else {
            $(this).show();
        }
    });
});

К сожалению, когда я получаю большое количество liэлементы, это значительно замедляется и иногда зависает в системе.Есть ли способ оптимизировать это или выполнить сначала весь поиск, а затем удалить все элементы li одновременно, чтобы система не зависала?

Когда я выполняю поиск на стороне сервера, я могу простоиметь загрузочный счетчик и обратный вызов при успешном завершении, но, похоже, это не относится к клиентской части.

Ответы [ 6 ]

4 голосов
/ 12 января 2012

Пара советов

Не запускать поиск по каждому событию keyup.Вместо этого, используйте короткий таймер (~ 200 мс), который ожидает следующего набора и начинает поиск, если его нет:

 keyup:
      clearTimeout(searchTimer)
      searchTimer = setTimeout(doSearch, 200)

Если query.length <=1, ваш цикл можно оптимизировать, нет необходимости проверять его на каждомитерация.

each(li)...find(span) слишком много служебной информации.Попробуйте выполнить итерацию напрямую через промежутки:

$('.friends-list li span').each(function() {
    var p = $(this);
    if(p.text().toLowerCase().indexOf(query) !== 0) {
        p.parent().hide();
    } else {
        p.show();
    }
});

Также обратите внимание на некоторые незначительные оптимизации в приведенном выше коде.

3 голосов
/ 12 января 2012

Я бы также предложил использовать цикл, поскольку он значительно быстрее .

2 голосов
/ 12 января 2012

Я бы посоветовал задержать нажатие клавиш, чтобы вы не выполняли поиск, пока пользователь не перестанет набирать текст в течение некоторого времени, скажем, полсекунды, хотя вы можете попробовать это и настроить по вкусу.,Кроме того, я внес несколько небольших изменений в ваш поиск, например, если вы знаете, что строка поиска слишком короткая, вы просто хотите показать все, поэтому в этом случае не нужно тестировать каждый элемент в цикле.

(function() {
   var timerID = null;

   function doSearch(query) {
     var length = query.length;

     if (length <= 1) {
        $('.friends-list li').show();
     } else {
        $('.friends-list li').each(function(){
           var $this = $(this);
           if($this.find('span').text().toLowerCase()
                                       .substring(0, length) != query)
              $this.hide();
           else
              $this.show();
        });
     }
   } 

   $('.search-box').keyup(function(){
      var searchString = this.value.toLowerCase();

      if (timerID)
         clearTimeout(timerID);

      timerID = setTimeout(function() {
         timerID = null;
         doSearch(searchString);
      }, 500);
   });
)();
2 голосов
/ 12 января 2012

Отсрочка обновления DOM - эффективный способ ускорить код, подобный этому. Делайте их все в конце, а не во время цикла .each ().

0 голосов
/ 03 сентября 2012

И я знаю, что это старый, но рассмотрим лучшие селекторы, элементы кэширования и всплывающие события (здесь не применимо) - ищите оптимизацию jQuery, и вы получите кучу отличных советов.

0 голосов
/ 12 января 2012

В настоящее время вы запускаете полный поиск при каждом нажатии клавиши.Вы можете подождать немного времени.Скажите 0,2 секунды и проверьте, была ли нажата другая клавиша.Небольшая задержка должна быть удобной для пользователя, даже едва заметной, но если кто-то набирает слово (быстрое нажатие клавиш), это может сэкономить многие из этих итераций, увеличивая опытную скорость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...