iMarkDesigns
iMarkDesigns

Reputation: 1262

jQuery Loop that slows your browser

I'm creating online chat, but I'm wondering while using jQuery .load() in my script, my browser seems to get slow. When i checked the inspect element "Net" section, it loads bunches of GET-data... etc.

I would like to know if there's a better script solution with this code to prevent chat being heavy in the background while the data keeps looping in the background to check who's keep coming online/offline.

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

the Chat-Side-Panel will be the main panel, and LI will be the listings of users including their status (online/offline) and flag (message received). As for the standard, what can you suggest for the setInterval time loading (if 5sec. is enough) or should i increase it.

Thanks for your input for this.

PS. We're doing this with both PHP/MySQL also.

Upvotes: 1

Views: 86

Answers (2)

Bellash
Bellash

Reputation: 8184

Last years (around 2012) I developed a chat system for a social network, and saw that

Using setInterval issue is when the request is being sent regularly, without waiting or carry about the result of the first requests in the queue. Sometimes the script can not respond and Mozilla or IE asks the user whether he should block or wait for the non-responding script.

I finally decided to use setTimeout instead. Here is what I did (I use $.getJSON so please study the example and how can use load instead)

    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.: I would like to mention that the time depends on our many items are to be retrieved in your users.php file. Maybe you should use the paging tip. Your users.php can then treat url params users.php?page=1&count=100 for the first request, users.php?page=2&count=100 for the second until the results rows number is 0.

EDITS: In addition, I suggest you consider not interacting with the DOM every time. It is important too.

Upvotes: 1

JAAulde
JAAulde

Reputation: 19560

One issue I see is that you keep re-querying the DOM for the same elements. Get them once, re-use them thereafter:

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

I don't know all of your involved logic or what the rest of your system looks like, so this particular code may not work exactly. It should simply serve as a re-factor done in a vacuum to show what that function could look like if you stopped hitting the DOM so hard.

Also, use of setInterval is not generally recommended. If the load of the remote file takes a while, you could end up calling loadThis() again before a previous one was completed. This would compound your DOM issues if calls to loadThis() began stacking up. Recursive use of setTimeout is preferred in a situation like this. Here is the above code modified to run recursively, and some usage examples below that:

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'));

Upvotes: 2

Related Questions