I am building a game with a requestAnimationFrame
loop that includes a call to jQuery html()
method. It just updates the text in a status window next to the game action.
I notice with Chrome's timeline monitor, that the DOM nodes go up and up and up, thousands in a minute! And when I change my code from:
// creates a ton of DOM nodes
$("#readout").html(data);
to
// DOM nodes does not increase over time
document.getElementById('readout').innerHTML = data;
the 'memory leak' goes away.
jQuery html() Method The html() method sets or returns the content (innerHTML) of the selected elements. When this method is used to return content, it returns the content of the FIRST matched element. When this method is used to set content, it overwrites the content of ALL matched elements.
html() is used to return or change the html and text content of an element. text() can only return or change the text content of an element.
Short answer: No.
Long answer: You likely have something else going on in your page/code.
A memory leak is generally caused by a circular reference between the Javascript engine and the DOM. For example:
var div = document.getElementById('divId');
div.onclick = function() {
doSomething(div);
};
The script obtains a reference to a div on the page. So far we're fine. The next line assigns a function to an event handler on the DOM, creating a reference from the DOM to the Javascript engine - half way to a leak. The function body uses the tag, which creates a Closure - the tag reference is kept with the function for future calls to it. That completes the circular reference between the tag -> function (DOM -> JS) and function -> tag (JS -> DOM), and so the 2 will sit in memory until the browser's process is destroyed.
So in order for either line of code you mentioned to leak, it would have to be eliminating tags that had events attached like above (or data that follows a similar pattern). But, jQuery's .html(string) goes out of its way to prevent these:
// Remove element nodes and prevent memory leaks
elem = this[i] || {};
if ( elem.nodeType === 1 ) {
jQuery.cleanData( getAll( elem, false ) );
elem.innerHTML = value;
}
So it's looping through all the tags inside the tag you're running .html(string) on and running cleanData() on them, which in turn does this:
jQuery.removeEvent( elem, type, data.handle );
Thus preventing the leak.
So in order to leak memory with this method and not the browser built-in .innerHTML you'd have to be triggering some very obscure browser bug (seems pretty unlikely), or more likely something else is going on and you're mistaking it for jQuery's .html(string).
Always use .empty().html(...)
instead of just .html()
.empty()
unbinds the event listeners from the DOM objects you are about to remove, and removes them gracefully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With