1

I'm developing a project which makes heavy use of Javascript, and includes a lot of DOM manipulation. As the code grows, I noticed that sometimes there is a delay (about 1-2 seconds) of Javasript execution on page load under Internet Explorer (9). This delay never happened on Firefox.

For example:

// the actual code contains much more stuff
$("body").append("<p>paragraph</p>");

Although the p was generated dynamically, it should be seen right after page loads on modern browsers. But on IE, sometimes I can clearly see the p was being added after all static content loads, which makes the whole page jumpy.

If I restarted IE, the delay's gone. However, it would occur again on next page refresh if a lot of DOM manipulation has been done.

So I'm thinking if this was caused by memory leak since I rarely nullify object references.

var foo = $("#foo");
foo.on("click", function() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
    // nullify bar
    bar = null;
});
// nullify foo
foo = null;

Questions:

  1. Should I nullify every object reference when they are done being used like in the example above?

  2. If the answer to Q1 is no, when or in what condition should I nullify object references?

  3. What else could I do to prevent memory leaks besides nullifying?

PS: I'v read some similar questions asked a few years ago, they are mostly for IE 6/7.

SCGH
  • 887
  • 8
  • 13
user1643156
  • 4,407
  • 10
  • 36
  • 59
  • Have you tried nullifying objects and then testing to see what happens with the memory leak? There aren't generally super clear-cut answers to these types of things. Profiling and optimizing based on that profiling might be the best you can do. But hopefully someone has a better response :) – maxedison Feb 23 '13 at 14:32
  • I'm not sure that you can outdo the performance of IE's garbage collector, but I could be wrong. If you are using `.append` and similar functions a lot, especially in a loop, it uses a lot of memory; you may want to see if you can cut back on that a little – Explosion Pills Feb 23 '13 at 14:33
  • in this particular example, setting the variables to null wont help you. you can read up on ie specific strategies(ie has specific problems with the dom and garbage collection). but first...measure memory to make sure you really have a memory leak. – goat Feb 23 '13 at 14:33
  • If you are doing something with a loop, @ExplosionPills' suggestion would be implemented by just concatenating all the html in a string during the loop, and then appending the entire thing just once after the loop has finished. – maxedison Feb 23 '13 at 14:36
  • @maxedison No, I haven't taken the time to nullify all objects since the code is a bit long and complex. And actually I'm not quite sure `how to trigger the problem` in my project. It seems to happen randomlly for now. – user1643156 Feb 23 '13 at 14:43
  • A thing to watch out for is a pattern that involves repeatedly adding content and then checking for layout details. For example, adding a `

    ` and then after appending it querying it's `.position()` or `.outerHeight()`. That forces the browser to recompute the layout, and it's expensive if you do it a lot.

    – Pointy Feb 23 '13 at 14:51
  • @rambocoder For `bar = null` in my example, I thought I was doing some similar to `jQuery source (v1.9.1 line 1539)`. Aren't they the same in theory? – user1643156 Feb 23 '13 at 14:59
  • you are nulling a string. they are nulling dom element references in line 1539 (`container = div = tds = marginDiv = null;`) – goat Feb 23 '13 at 15:02
  • @rambocoder that's right, my bad. but how about `foo = null`? won't it make a difference more or less by nullifying the object reference? – user1643156 Feb 23 '13 at 15:10

1 Answers1

4

Should I nullify every object reference when they are done being used like in the example above?

No, that's overkill.

If the answer to Q1 is no, when or in what condition should I nullify object references?

When you don't need it any more but it is in the scope of still living functions. In your example, foo could be referenced from the click handler, and therefore it won't be garbage collected as long as the handler is attached to the DOM. Yet there is no reason to nullify bar.

What else could I do to prevent memory leaks besides nullifing?

  • Do not use variables at all. In your example, you can simply use chaining: $("#foo").on(…);
  • Declare your handler functions in a different scope if they are unrelated to the execution context where they are used:
$(document).ready(function() {
    var foo = $("#foo");
    foo.on("click", showBar);
    // do anything else with `foo`
});
function showBar() {
    var bar = '<div id="bar">bar</div>';
    $("body").append(bar);
});

I'v read some similar questions asked a few years ago, they are mostly for IE 6/7.

That's because IE6/7 have some bugs in their garbage collector (javascript, circular references and memory leaks, MSDN articles). Yet, the techniques mentioned above are unrelated to that, they assume a correct-working GC. And with optimizing GCs, they may not even be needed, V8 for example does collect variables that actually are in scope but are not used again (Debugging Revealing Module Pattern: functions not in scope until called?).

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375