1

I have a website that uses a lot of AJAX requests, almost 1 every 2-3 seconds.

One thing I realized is that if I leave the page up for more than 20 minutes, it starts eating through the RAM on the machine with it pulled up (the server never struggles).

//Get the recent activity for the account
function getRecentActivity() {
    $.ajax({
        url: baseAPIurl + APIversion + "user/activity/",
        type: "GET",
        data: {
            user_id: ****
        },
        datatype: "json",
        success: function (e) {
            $("#recent_activity").empty();
            if (e.status == "success" && e.results != null) {
                $.each(e.results, function (e, t) {
                    if (t["campaign_type"] == "radio") {
                        $("#recent_activity").append('<li><a href="/***?id=' + t["campaign_id"] + '"><span class="label label-blue"></span>' + t["campaign_name"] + " - " + t["user_info"]["first_name"] + " " + t["action"] + '<br /><span class="pull-right text-muted small">' + t["timestamp"] + "</span></a></li>");
                    }
                    if (t["campaign_type"] == "online") {
                        $("#recent_activity").append('<li><a href="/***?id=' + t["campaign_id"] + '"><span class="label label-blue"></span>' + t["campaign_name"] + " - " + t["user_info"]["first_name"] + " " + t["action"] + '<br /><span class="pull-right text-muted small">' + t["timestamp"] + "</span></a></li>");
                    }
                })
            } else {
                $("#recent_activity").append('<li><a href="#"><span class="label label-blue"></span>No Recent Activity<span class="pull-right text-muted small">&nbsp;</span></a></li>');
            }
        }
    })
}

What is a better way to make so many requests, and not use 1GB or more of RAM?

Brian Logan
  • 812
  • 2
  • 6
  • 20
  • How do you trigger periodic ajax requests? – Cheery Oct 01 '14 at 05:46
  • Thank you Andreas for the edits, I have been looking at this screen for 12+ hours... – Brian Logan Oct 01 '14 at 05:46
  • @Cherry `window.setInterval`? –  Oct 01 '14 at 05:47
  • @BrianLogan nevermind ;) I've tried to keep the question as slim as possible. –  Oct 01 '14 at 05:47
  • @Cheery, I have a simple `setInterval(function() getRecentActivity() }, 5000)` for now, but I am working on making it more dynamic based on the people online. – Brian Logan Oct 01 '14 at 05:48
  • possible duplicate of [Browsers keep eating memory with AJAX + setInterval](http://stackoverflow.com/questions/5702833/browsers-keep-eating-memory-with-ajax-setinterval) –  Oct 01 '14 at 05:49
  • 2
    Every ajax call appears to be adding more elements to the DOM. That can accumulate over time, eating more and more RAM. – jfriend00 Oct 01 '14 at 05:50
  • @AndreasNiedermair the problem is that the requests fully complete in under a second. – Brian Logan Oct 01 '14 at 05:50
  • @jfriend00 even if they are removing the previous elements? What is a good way to bypass that? – Brian Logan Oct 01 '14 at 05:51
  • @BrianLogan using eg `.html()` or `.innerHTML` instead of `.append()` and `.empty()`/... https://forum.jquery.com/topic/memory-leaks-with-ajax-calls –  Oct 01 '14 at 05:52
  • But, you aren't removing the previous elements. You're using `.append()`. If you do remove previous elements so there is no accumulation in the DOM, that should fix one memory accumulation issue. – jfriend00 Oct 01 '14 at 05:52
  • jfriend00 I am running a .empty() at the start of the function, which is dumping the entire container. @Andreas should I just use .html() instead? – Brian Logan Oct 01 '14 at 05:53
  • 2
    `.empty()` should take care of it fine and is better than other ways to clear it because `.empty()` cleans up any relevant jQuery data too. I didn't see the `.empty()` before. Back to ground zero. – jfriend00 Oct 01 '14 at 05:55
  • @BrianLogan I know, a bit awkward to ask that late, but: what have you tried so far? which scenarios did you try? did you use any tools yet (to investigate the memory itself, eg Compuware AJAX Edition)? –  Oct 01 '14 at 05:57
  • @BrianLogan please add the information on `.empty()` to your question! –  Oct 01 '14 at 05:59
  • I am testing the `.html()` right now, give me a second, if it appears to fix it for the most part, I will just go with that. – Brian Logan Oct 01 '14 at 06:01
  • The `.html()` solution seems to have fixed it. In fact, the RAM usage has gone down below other webpages O.o Thanks everyone! @Andreas, would you like to post the answer so I can approve it since you did post the answer first? – Brian Logan Oct 01 '14 at 06:05
  • @BrianLogan I would be very happy to do that –  Oct 01 '14 at 06:08
  • It will still accumulate as every http request during a session is stored by the browser. you can access it with window.performance but it's nothing compared to leaking through improper DOM replacement :) – Winchestro Oct 01 '14 at 06:25
  • Did you consider using websockets? – Winchestro Oct 01 '14 at 06:27
  • @Winchestro thanks for the idea, I have started using websockets, and oh my, they helped a lot. Keeps the local RAM usage down, and makes it even faster than AJAX requests would be. 100000x better. Thanks for the suggestion! – Brian Logan Nov 20 '14 at 18:15

2 Answers2

1

Instead of appending html elements to the DOM you should be just be replacing them. This should solve the problem.

Example from your code snippet:

$("#recent_activity").html('

  • ' + t["campaign_name"] + " - " + t["user_info"]["first_name"] + " " + t["action"] + '
    ' + t["timestamp"] + "
  • ");
    Vickrant
    • 1,233
    • 2
    • 9
    • 15
    • please see the comments. "jfriend00 I am running a .empty() at the start of the function, which is dumping the entire container." –  Oct 01 '14 at 05:59
    1

    As requested by the OP, I am taking this from my comments:

    Instead of doing .empty() and .append(), you could try to go for .html() or .innerHTML (which would be even more vanilla).
    I am suspecting some jQuery internal caching for every .append()-call, but this could be easily proven by using eg Compuware AJAX Edition (to inspect the memory itself).