【问题标题】:Is it possible to optimize Javascript client-side search?是否可以优化 Javascript 客户端搜索?
【发布时间】:2012-02-08 07:01:30
【问题描述】:

这是我用来对无序列元素列表进行排序并根据用户查询删除它们的 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 元素,这样系统就不会挂起?

当我进行服务器端搜索时,我可以只有一个加载微调器和一个成功回调,但似乎同样不适用于客户端。

【问题讨论】:

  • 这只是随机出现在我的信息流中,好问题...投赞成票!

标签: javascript jquery html search client


【解决方案1】:

几个小窍门

不要在每个 keyup 事件上触发搜索。相反,有一个短的计时器(~200ms)等待下一次按键并在没有按键时开始搜索:

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

如果 query.length <=1 您的循环可以优化掉,则无需在每次迭代时检查。

each(li)...find(span) 开销太大。尝试直接通过 span 进行迭代:

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

还要注意上面代码中的一些小优化。

【讨论】:

  • 我原则上同意你关于直接在跨度上循环的观点,但这确实假设没有没有子跨度的列表项。如果可以确认,那么是的,绝对按照你的方式去做。 (另外,你的意思可能是p.parent().show();
  • @nnnnnn,你说得对,我们需要更多地了解他们的 html 布局。
【解决方案2】:

我还建议使用 for 循环,因为它是 significantly faster

【讨论】:

    【解决方案3】:

    延迟 DOM 更新是加速此类代码的有效方法。在最后做所有这些,而不是在你的 .each() 循环中。

    【讨论】:

      【解决方案4】:

      我建议延迟击键,这样您就不要进行搜索,直到用户停止输入一段时间(例如半秒),但您可以尝试一下并调整它以适应口味.另外,我对您的搜索进行了一些小的更改,例如,如果您知道搜索字符串太短,您只想显示所有内容,因此在这种情况下无需在循环中测试每个项目。

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

      【讨论】:

        【解决方案5】:

        目前,您在每次击键时都会触发一次完整搜索。您可能需要等待一小段时间。说 0,2 秒并检查是否按下了另一个键。对于用户体验来说,小的延迟应该是可以接受的,甚至几乎不会被察觉,但如果有人正在输入一个单词(快速连续按键),这可以为您节省许多迭代,从而提高体验速度。

        【讨论】:

          【解决方案6】:

          而且我知道这已经过时了,但考虑更好的选择器、缓存元素和事件冒泡(此处不适用)- 搜索优化 jQuery,你会得到一堆很棒的提示。

          【讨论】:

            猜你喜欢
            • 2014-03-20
            • 1970-01-01
            • 1970-01-01
            • 2015-01-02
            • 1970-01-01
            • 1970-01-01
            • 2011-05-28
            • 2012-07-24
            • 1970-01-01
            相关资源
            最近更新 更多