【问题标题】:jQuery Loop that slows your browser让浏览器变慢的 jQuery 循环
【发布时间】:2014-05-04 22:13:27
【问题描述】:

我正在创建在线聊天,但我想知道在我的脚本中使用 jQuery .load() 时,我的浏览器似乎变慢了。当我检查检查元素“Net”部分时,它会加载一堆 GET 数据......等等。

我想知道此代码是否有更好的脚本解决方案,以防止后台聊天变得繁重,同时数据在后台不断循环以检查谁继续在线/离线。

setInterval('loadThis()', 5000);

function loadThis () {
  $("#loads").load('includes/users.php', function(){
    $(".chat-side-panel li").each(function(i){
      i = i+1;
      $(this).addClass("stats"+i);
      var status = $(".stats"+i).find("span.bullet").data("status"),
          flag = $(".stats"+i).find("span.mail").data("flag");
      if(status == 1) {
        $(".stats"+i).find("span.bullet").addClass("online");
      }
      if(flag == 1) {
        $(".stats"+i).find("span.mail").addClass("active");
      }
    });
  });
}

Chat-Side-Panel 将是主面板,LI 将是用户列表,包括他们的状态(在线/离线)和标志(收到的消息)。至于标准,您对 setInterval 时间加载有什么建议(如果 5 秒就足够了)还是应该增加它。

感谢您对此的意见。

PS。我们也同时使用 PHP/MySQL。

【问题讨论】:

  • 每次“加载”,加载了多少用户的状态?
  • 嗯,这取决于将注册多少。但是,如果您说会话中有多少人会在线,那么举个例子,10 个用户……在线和离线混合。

标签: php jquery mysql ajax json


【解决方案1】:

我看到的一个问题是您不断地重新查询 DOM 以获得相同的元素。获取一次,然后重复使用:

var load_target = $('#loads');
function loadThis () {
    load_target.load('includes/users.php', function () {
        load_target.find('.chat-side-panel li').each(function (i) {
            var stats_li = $(this),
                bullet = stats_li.find('span.bullet'),
                mail = stats_li.find('span.mail');

            bullet.toggleClass('online', (bullet.data('status') == 1))
            mail.toggleClass('active', (mail.data('flag') == 1));
        });
    });
}

我不知道您所涉及的所有逻辑或系统的其余部分是什么样的,因此此特定代码可能无法完全正常工作。它应该只是作为一个在真空中完成的重构,以显示如果你停止如此用力地敲击 DOM,该函数会是什么样子。

此外,通常不建议使用setInterval。如果远程文件的加载需要一段时间,您最终可能会在前一个文件完成之前再次调用loadThis()。如果对loadThis() 的调用开始堆积,这将使您的DOM 问题更加复杂。在这种情况下,最好递归使用setTimeout。以下是修改为递归运行的上述代码,以及下面的一些使用示例:

var load_target = $('#loads'),
    loadThis = function (start_cycle) {
        $.ajax({
            url: 'includes/users.php',
            dataType: 'html',
            type: 'GET',
            success: function (response) {
                load_target
                    .html(response)
                    .find('.chat-side-panel li').each(function (i) {
                        var stats_li = $(this),
                            bullet = stats_li.find('span.bullet'),
                            mail = stats_li.find('span.mail');

                        bullet.toggleClass('online', (bullet.data('status') == 1))
                        mail.toggleClass('active', (mail.data('flag') == 1));
                    });
            },
            complete: function () {
                if (typeof start_cycle !== 'boolean' || start_cycle) {
                    load_target.data('cycle_timer', setTimeout(loadThis, 5000));
                }
            }
        });
    };

//to run once without cycling, call:
loadThis(false);


//to run and start cycling every 5 seconds
loadThis(true);
// OR, since start_cycle is assumed true
loadThis();


//to stop cycling, you would clear the stored timer
clearTimeout(load_target.data('cycle_timer'));

【讨论】:

  • 您好 JAAulde 大师,您的代码让我的浏览器保持“无响应”......感谢您的想法。非常感谢!
【解决方案2】:

去年(大约 2012 年)我为社交网络开发了一个聊天系统,并看到了

使用setInterval 的问题是定期发送请求,无需等待或携带队列中第一个请求的结果。有时脚本无法响应,Mozilla 或 IE 会询问用户是否应该阻止或等待无响应的脚本。

我最终决定改用setTimeout。这是我所做的(我使用$.getJSON,所以请研究示例以及如何使用负载代替)

    function loadThis () {
       $.getJSON('url').done(function(results){
          //--use the results here
          //then send another request
          setTimeOut(function(){
               loadThis();
           },5000);
       }).fail(function(err){
          //console.log(print(err))
          setTimeOut(function(){
               loadThis();
           },1000);
       });
    }
    loadThis();

PS.:我想提一下,时间取决于我们要在您的users.php 文件中检索的许多项目。也许您应该使用分页提示。然后,您的 users.php 可以将 url 参数 users.php?page=1&count=100 处理为第一个请求,users.php?page=2&count=100 处理第二个请求,直到结果行数为 0。

编辑:此外,我建议您考虑不要每次都与 DOM 交互。这也很重要。

【讨论】:

  • 贝拉什大师您好,我很喜欢学习这个东西。我很感激你的意见,并会做你的建议。再次感谢您提出这个想法。
猜你喜欢
  • 2011-09-23
  • 2014-04-17
  • 1970-01-01
  • 2012-08-21
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多