【问题标题】:Speeding up jQuery/Javascript search function加速 jQuery/Javascript 搜索功能
【发布时间】:2017-05-16 06:41:54
【问题描述】:

我有一个包含 3000 多个具有唯一名称的项目的列表。它们都像这样包裹在 UL 标签内:

<ul>
    <li><a href="#"> Item_ID125167</a></li>
    <li><a href="#"> Item_ID146324</a></li>
</ul>

然后我有一个这样的搜索输入:

<input type="text" id="searchfield" class="form-control" placeholder="Search">
<span class="input-group-addon">
    <button type="submit" id="searchButton" onclick="filterByName()">
        <span class="glyphicon glyphicon-search"></span>
    </button>
</span>

最后是隐藏/显示匹配项的功能:

function filterByName() {
  $("li").each(function(index) {
    if ($(this).children('a').text().toUpperCase().indexOf($("#searchfield").val().toUpperCase()) > -1) {
      $(this).css('display', "");
    } else {
      $(this).css('display', "none");
    }
  });
}

在使用旧的 android 手机时,这感觉有点慢,有 3000 多个项目。搜索功能有更好的解决方案吗?

【问题讨论】:

  • 使用 find() 代替 children()。 Find 使用本机浏览器功能,通常速度更快。
  • 我的建议是不要在单个页面上显示所有 3000 个项目,而是将它们拆分为页面(分页技术),以便每个页面显示 50-100 个项目。通过这样做,您可以显着减少循环的开销并大大提高性能。实际上,没有人愿意滚动查看长列表,这就是为什么所有在线购物网站都使用分页技术的原因
  • 搜索是否仍然能够从分页的第 20 页快速挑选项目?
  • 它应该在服务器端执行。您在服务器上有 3000 个项目,当有人按名称搜索特定项目时,该名称将在已存在 3000 个项目的服务器上查看,并返回结果以显示在浏览器中
  • 这种技术在每个地方(谷歌、易趣、亚马逊......)都实现了,所以您需要做的就是向服务器发送请求,让服务器进行过滤工作,然后将结果返回给您并显示这些结果浏览器,简单快速

标签: javascript jquery performance search


【解决方案1】:

加快速度意味着您应该尽可能地重用资源

var $list = {}; // initialize an empty global scope variable to keep your elements in
function filterByName(searchString) {
  //reusing $list will prefent you from walking the dom each time
  $list.each(function(index, el) {
    el.style.display = el.title.indexOf(searchString) > -1 ? "list-item" : "none";
  });
}

function loadList() {
  $list = $('#results').find('li'); //faster than $('#results > li');
  $list.each(function(index, el) {
      //save the uppercase search values in a propery to search faster
      //this saves you from running .toUpperCase() on every search
      var text = el.textContent || el.innerText;
      el.setAttribute('title', text.trim().toUpperCase()); //using title makes a faster search later
      $list[index]=el;
  }); 
}

$(function() {
    loadList();
  $('#searchButton').click(function(e){
    e.preventDefault();
    //prepariung the search sring here saves processing during search
    filterByName($("#searchfield").val().trim().toUpperCase());
    return false;
  });
  //if your list is build dynamicly simple run loadList() every time changes to the list content may happen
});

看到一个有效的小提琴 https://jsfiddle.net/q1x7ujex/

【讨论】:

  • 我选择了这个,现在它快了大约 4 倍。谢谢:)
【解决方案2】:

根据我的测试,find 在这种情况下会比children 运行得更快。
你可以通过Test selectors自己运行,或者查看结果:

如果您的眼睛没有任何改善,您可以使用我添加到您的功能中的console.time查看结果,它会记录操作到浏览器所花费的时间。

function filterByName() {
 //Instead of selecting the search field + getting it's value + toUpperCase 
 //*3000 times this way it will only happen once.
 var searchVal = $("#searchfield").val().toUpperCase();

//measures the time it takes for the operation
 console.time("test");
 $("li").each(function() {

    //find is faster than children
    if ($(this).find("a").text().toUpperCase().indexOf(searchVal >-1)) {
        this.style.display = '';
    } else {
        this.style.display = 'none';
    }
});
//Will write to the console the time it the operation took.
console.timeEnd("test");
}

【讨论】:

  • 谢谢!这些对我来说是一些新信息:)
【解决方案3】:

我希望这段代码比你的代码运行得快一点。试试看

function filterByName() {
    var searchVal = $("#searchfield").val.toUpperCase();
    $("li").each(function() {
        if (this.children[0].textContent.toUpperCase().match(searchVal)) {
            this.style.display = '';
        } else {
            this.style.display = 'none';
        }
    });
}

【讨论】:

  • 感觉速度一样。我认为是 DOM 操作显示/隐藏需要这么长时间。
【解决方案4】:

据此页面:https://learn.jquery.com/performance/optimize-selectors/

你必须使用find 而不是children(它说超级快)

您可以做的其他事情是从该列表创建一个数组并使用jQuery.inArray

【讨论】:

  • 我切换到查找,但感觉速度仍然相同:/
  • 您对字符串进行了大写操作...您将为不区分大小写的 indexof 创建一个 protptype
  • 什么?我真的不明白你的意思。
  • 他的意思是你首先将每个文本都大写然后比较。如果你有类似 indexOf 的函数会更快,它不关心大小写
  • 我需要区分大小写的项目名称
猜你喜欢
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
相关资源
最近更新 更多