Reputation: 1262
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
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
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