jQuery - Internet Explorer memory leaks

2019-07-21 20:38发布

问题:

I'm developing an internal web application for use on the helpdesk on which I work, designed to be run fullscreen, all the time, on large TVs around the room, displaying relevant data for the guys taking calls. We're using Internet Explorer 8 on Windows 7 (company security policy doesn't allow for any other browser) and jQuery 1.6.2. All the scripts and data are stored on the LAN - nothing's coming off the internet.

Essentially the application queries several XML files (generated by server scripts) to display current information such as:

  • statistics for each call queue such as the number of calls waiting (reloaded every 5 seconds)
  • current announcements (displayed in a slideshow format using jQuery cycle, reloaded when it gets to the end of the current list of announcements)

In my testing in Firefox and Chrome etc, everything works beautifully. But in Internet Explorer, if the page is left open for more than 10 minutes or so at a time, the whole browser starts to freeze up and crash.

I've done a fair bit of research into javascript/jQuery memory leaks, and while I've found a few interesting articles, most of them have to do with leaks that occur when creating or removing elements in jQuery - something I'm not doing.

The way I'm essentially working is:

  1. Load XML from script
  2. Iterate through each of a set of elements (eg, call queues), then assign relevant child elements to variables.
  3. Use those variables to put together a simple HTML string (using an array, I read that building strings that way is more memory efficient than building up a string using concatenation eg string = string + 'blarg';)
  4. HTML is output straight into the waiting container <div>, replacing whatever was in it before.

The whole thing looks something like

$.get('dashboard-queues.asp', function(data) {
    var allQueues = new Array();
    $(data).find('queue').each(function() {
        var thisQueue = new Array(); // array used to build HTML string for this queue

        var callsWaiting = parseFloat($(this).find('waiting').text());
        var activeCalls = parseFloat($(this).find('active').text());

        // (etc...)

        thisQueue.push("<div class='q-item'>"+callsWaiting+"</div>");
        thisQueue.push("<div class='q-item'>"+activeCalls+"</div>");

        // (etc...)

        allQueues.push(thisQueue.join(''));
    });

    $("#callboard").html(allQueues.join(''));
});

There's a bit of extra processing in there which changes the html code outputted for that piece of data in certain circumstances (eg to if there are too many calls waiting). Additionally, I do a little bit of processing after outputting the HTML - figuring out how many calls are waiting in total, the call abandon rate for the day etc - but that's all simple calculations.

I've been pretty careful to reset variables and arrays each time we loop through to make sure they're not retaining data. Doesn't seem to have helped much.

I can post more actual code if need be (didn't want to make this post too gigantic to start with). Can anyone see where I might be running in to any problems? If anyone can suggest more efficient or better ways of doing what I'm trying to do, that would be most welcome also.

Cheers :)

回答1:

If you have access to IE9 you could try hitting F12 and then select the profiler tab. I realise your requirement is for IE8 not 9, but this might at least help you profile where the problem may lie in terms of large anonymous chunks of poor performance.

Looking at your code, I'm not sure if perhaps the main $.get would be acting as a closure. I'm fairly certain JQuery deals with closures properly and garbage collects properly, but maybe IE8 isn't working as expected in this instance..?

apologies for the indirect non-answer... Good luck!

This comment seems like it may be of some relevance since you're dealing with DOM manipulation and event handling.