【问题标题】:javascript (jquery) script perfomance synchronous vs asynchronousjavascript(jquery)脚本性能同步与异步
【发布时间】:2012-03-02 17:35:46
【问题描述】:

我有一个基于输入文本变化过滤 dom 元素的 javascript 函数,所以:

$(".input").keyup(function(e) {
    filter();
});

var cache = $(".dom");

var filter = function() {
     cache.each(function() {
         // if field contains some text show else hide
     }
};

当有许多 dom 元素要过滤时,我的问题发生了,由于 同步处理(如上面的示例),整个页面都无法访问。我试图提出一个不通过同步处理锁定整个页面的解决方案。

问题与过滤逻辑无关(完全无关紧要),与 jquery 或 javascript 本身无关,与同步处理和 dom 元素的数量有关。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    由于 JavaScript 是单线程的,唯一真正解决这个问题的方法是将长时间运行的作业拆分为一系列较短的作业,并在每个部分的末尾使用带有短时间延迟的 setTimeout() 来踢关闭下一个。这使您的 UI 和其他 JavaScript 事件有机会更新。

    【讨论】:

      【解决方案2】:

      您可以通过将大量 dom 节点放入队列中来更新它们,并在每个 setTimeout“tick”上只处理几个元素。在伪代码中:

      on(event):
         queue = DOM nodes to be updated
         setTimeout(update)
      
      update:
          queue.slice(0, limit).each(...update a node...)
          queue = queue.slice(limit) // remove processed nodes
          if (queue.length > 0) setTimeout(update) // repeat...
      

      有关完整的工作示例,请参阅 http://jsfiddle.net/Etsmm/2/

      更新:第一个版本的 Chrome 存在问题(与它的“显示”错误有关),按照 this answer 添加修复似乎已经解决了问题。

      【讨论】:

      • 当我只输入数字 3 时,您的 jsFiddle 示例会冻结浏览器。
      • 您在重复问题中的评论指出 “这里有些人似乎发疯了。... filter() 函数的详细信息无关紧要,”提高您的第一个和第二个版本之间的性能?是在filter 中吗?是的。请再次告诉我,我疯了。
      • thg,该解决方案与我编写的解决方案相同,但以更智能的方式进行,因此我将使用它。谢谢。
      【解决方案3】:

      如果真的太长,或者通过 ajax 请求在其他地方进行? 而且,也许,某种方式:第一步,选择所有要隐藏在数组中的 ID,然后设置超时,然后在第二步中,将它们隐藏为 50 per 50? 此外,也许处理隐藏所有这些元素的容器,然后,一旦完成,重新显示它可能会更快?

      【讨论】:

        【解决方案4】:

        出于这种目的,我通常更喜欢 Ben Alman 的消息队列库。它也有不同的选择。这个在节流方面相当成功。

        https://github.com/cowboy/jquery-message-queuing/

        下面是一个节流示例

        http://benalman.com/code/projects/jquery-message-queuing/examples/throttling/

        【讨论】:

          【解决方案5】:

          感谢大家的帮助。我根据 Ben Clayton 的回应提出了一个解决方案,但我仍在寻找想法并研究 thg435 解决方案。任何 cmets 都将不胜感激。

              <script type="text/javascript">
          
                  $(document).ready(function () {
          
                      var cache = $(".whatever");
                      var wait = 0;
                      var input = $("#input");
                      var regex = null;
          
                      input.keyup(function (e) {
                          go.index = 0;
                          clearTimeout(wait);
                          wait = setTimeout(go.start, 500);
                      });
          
                      var filter = function (i) {
                          var one = cache.eq(i - 1);
                          one.text().match(regex) ? one.show() : one.hide();
                          go.index++;
                          setTimeout(go.filter, 10);
                      };
          
                      go = {
                          index: 0,
                          filter: function () {
                              go.index == 0 || go.index > cache.length ? null : filter(go.index);
                          },
                          start: function () {
          
                              go.index = 1;
          
                              var search = input.val();
                              search = search.replace(new RegExp("[a]", "gi"), "[aàáâã]");
                              search = search.replace(new RegExp("[e]", "gi"), "[eéê]");
                              search = search.replace(new RegExp("[i]", "gi"), "[ií]");
                              search = search.replace(new RegExp("[o]", "gi"), "[oóô]");
                              search = search.replace(new RegExp("[u]", "gi"), "[uú]");
                              search = search.replace(new RegExp("[c]", "gi"), "[cç]");
                              regex = new RegExp(search, "gi");
          
                              go.filter();
          
                          }
                      }
          
                  });
          
              </script>
          
              <input type="text" id="input" />
          
              <span class="whatever">lalala</span>
              <span class="whatever">leléLÉ</span>
              <span class="whatever">lololo</span>
              <span class="whatever">lululu</span>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多