1

I have a page that I want to update non stop, every few seconds.

For this, I wrote the following:

var to;
$(function () {
           to = setTimeout(updateDivContent, 2000);
});

function updateDivContent() {

    $('#topbox').load('/home/blabla', null);


    $('#leftgraph').load('/home/blabla', null, function () {

        to = setTimeout(updateDivContent, 2000);
    });
};

This worked, however, it leads to what I presume is a memory leak as after around 15 minutes, the computer almost freezes up with the browser taking up all available memory and CPU.

I am guessing that the Timeout is basically stacking, but, I am not sure how to fix this. I have tried getting rid of the second timeout and putting the first one inside a while(true) loop, but, I just couldn't get it to work.

Can anyone suggest anything?

wil
  • 2,019
  • 2
  • 15
  • 14
  • What you're already doing looks fine to me - you definitely do _not_ want a `while(true)` or similar. Does it still crash if you take the Ajax `.load()` calls out? (I know you obviously need them, but just for testing purposes...) – nnnnnn Jun 15 '12 at 11:28
  • have you tried clearing the timeout with `clearTimeout` before you set a new timeout? – WickyNilliams Jun 15 '12 at 11:30
  • @WickyNilliams - there's nothing to clear: the previous one has already executed before the new one gets set. – nnnnnn Jun 15 '12 at 11:33
  • Ignore me then :) I think i was confusing `setTimeout`/`clearTimeout` with `setInterval`/`clearInterval` – WickyNilliams Jun 15 '12 at 11:35

5 Answers5

9

This looks fine actually. But if the first Ajax call does not finish within two seconds, it will stack, and this could (don't know for sure) cause problems.

The timeout itself does not stack, since you are initiating a new one only after the previous one finished.

Try to initiate a new timeout once both Ajax requests finished:

$.when($('#topbox').load('/home/blabla'),
       $('#leftgraph').load('/home/blabla')
).then(function () {
    setTimeout(updateDivContent, 2000);
});

Reference: $.when

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • As far as I am aware, the Ajax should be finishing, it is coming off of the lan and is typically instant... If you are interested... this is what is happening - http://i.imgur.com/YmLMf.png ... I will try your changes.... I am just curious about the .load - will it completely replace/get rid of the item it is replacing? The "blabla" is a highcharts chart, and, I am wondering if it is being disposed/unloaded or stays in memory/similar.... only conclusion I can think of. – wil Jun 15 '12 at 11:53
  • Well, you didn't provide any information about the context or the content of the page you load ;) But yeah, if `/home/blabla` is JavaScript which creates global variables, then those will continue to exist, until they are overwritten or deleted. I think it's difficult to give any proper suggestion here, it would require a more detailed analysis of the code. – Felix Kling Jun 15 '12 at 11:59
  • no worries and have +1'ed this! I'll take out the updating of the charts and see what happens. – wil Jun 15 '12 at 12:02
  • No need to up-vote if it does not help ;) Maybe your question is just not solvable through SO. – Felix Kling Jun 15 '12 at 12:04
  • 1
    @wil have you considered doing some javascript profiling with chrome? – WickyNilliams Jun 15 '12 at 12:14
  • @WickyNilliams This really isn't my specialty at all :/ ... The problem is, I need to redraw the chart without flicker... doing .load() works fine, but, seems to cause this problems... tried a few other methods such as calling .empty() first seem to cause a flicker... just not sure of a better way of doing this, but, I may try to ask another question soon on it. – wil Jun 15 '12 at 14:23
  • @wil: Do you mean it is the same chart but with different data? You can just update the existing chart and Highcharts even provides nice animations. Have a look at their documentation, this is probably what you should be doing. – Felix Kling Jun 15 '12 at 14:24
  • @FelixKling Yep, it is the same chart - I have isolated just the script that Highcharts takes and have a MVC method that generates it - by using the .load(), I basically replace that script element... it does appear to work - just didn't realise that it was responsible for this memory leak - but, it makes sense. – wil Jun 15 '12 at 14:35
  • Well, I am happy to upvote and will mark as answer... thanks for saying what I did was correct, and for giving the better code. from my limited understanding of the Chrome tools, I believe that it is Highcharts that are responsible - http://imgur.com/fJutH and I just have to find a better way of dealing with it. – wil Jun 15 '12 at 15:04
1

I think it is better to use setInterval instead of setTimeOut.

See this post.

Community
  • 1
  • 1
Mathieu
  • 3,073
  • 1
  • 19
  • 25
  • Normally I'd agree but there's an asyncronous HTTP request in play here too, which may take longer than your interval to return the response. – Graham Jun 15 '12 at 11:29
  • `setInterval` is worse, because the timing of the Ajax `.load()` function is variable. Better to use `setTimeout` in the complete callback of the `.load()` as already shown. – nnnnnn Jun 15 '12 at 11:30
  • Then is't it better to do the next call in the OnComplete-event of the AJAX request? – Mathieu Jun 15 '12 at 11:31
0

You probably want to call clearTimeout to invalidate the previous timer, like this:

clearTimeout(to);
to = setTimeout(updateDivContent, 2000);
Graham
  • 6,484
  • 2
  • 35
  • 39
0

can you this it will call ever 2 second

to = setInterval("updateDivContent", 2000);


function updateDivContent() {

$('#topbox').load('/home/blabla', null);


$('#leftgraph').load('/home/blabla', null, function () {

    //to = setTimeout(updateDivContent, 2000); 
});
};
Muthukumar M
  • 1,138
  • 10
  • 19
  • 1
    `setInterval` is worse, because the timing of the Ajax `.load()` function is variable. Better to use `setTimeout` in the complete callback of the `.load()` as already shown. – nnnnnn Jun 15 '12 at 11:31
0

Try setInterval:

var to;

$(function () {
    to = setInterval(updateDivContent, 2000);
});

function updateDivContent() {
    $('#topbox').load('/home/blabla', null);
    $('#leftgraph').load('/home/blabla')
};
iappwebdev
  • 5,880
  • 1
  • 30
  • 47