Situation: I'm working on a pretty decently complex single page Backbone app that could potentially be running for 8-12+ hours straight. Because of this, there's a need to ensure that the application won't leak and have a reputation for crashing after X hours or slow down dramatically.
The Application: The app is built on Backbone (mv*), Zepto (similar to jquery), Curl (amd loader) & Mustache (templating).
Problem: I've just conquered the event listeners. The garbage collector seems to be doing a fine job cleaning these guys up, but the DOM Node Count won't stop climbing.
Questions:
I'm really just looking for a head start on my adventure to stop these DOM Nodes from rising. Any help or guidance would be greatly appreciated (and accordingly upvoted).
I assumed that once the event listeners were properly disposed of that the DOM Node Count would just manage itself, but this doesn't seem to be the case.
Edit: Without the Timeline recording, I reran the same script to randomly mash links and took a screenshot at around the 7 minute mark. After GC came through I had these results.
Edit: After Fix:
After Upgrade Backbone and using listenTo and stopListening everywhere
Backbone. Backbone has been around for a long time, but it's still under steady and regular development. It's a good choice if you want a flexible JavaScript framework with a simple model for representing data and getting it into views.
Backend Synchronization BackboneJS is use with the front-end and back-end systems, allows the synchronization with the backend to provide support to RESTful APIs.
You can use the Backbone. Model without jQuery, but Backbone. View will require either jQuery or Zepto, just like the docs state.
It is designed for developing single-page web applications, and for keeping various parts of web applications (e.g. multiple clients and the server) synchronized. Backbone was created by Jeremy Ashkenas, who is also known for CoffeeScript and Underscore. js.
I assumed that once the event listeners were properly disposed of that the DOM Node Count would just manage itself, but this doesn't seem to be the case.
If I got you right you are trying to dispose of the node by removing listeners from it, is that the case?
Note that adding event listener to a DOM node doesn't prevent the node from being garbage collected, the dependency is in opposite direction: while the node is alive the listener function will not be collected.
- Is there a proper way to dispose of DOM Nodes so that they will be properly garbage collected, or is this DOM Node Count a running total that will never decrease?
To make sure a DOM node can be garbage collected you should
So it is not enough to just remove listeners from a node to make it collectable. Moreover, it is not necessary to remove listeners from a node if you want the node to be collected.
The DOM node count should be decreasing when some nodes are collected by GC and destroyed. The number indicates current amount of DOM nodes that have been created but not destroyed so it shouldn't grow indefinitely unless there is a memory leak.
- Is the DOM Node Count even a reliable figure?
Yes. It should be a reliable figure as it is incremented whenever a new DOM node is created and decremented when it is destroyed. So the implementation is quite straightforward to trust it.
It's fixed! - UPGRADE BACKBONE. (continue reading)
After 7 minutes of running the same stress-test, these are the results:
Results: 7.0 minutes, 6,926 DOM Nodes (Without the timeline recording) and the Event Listener Count looks like BLUE BLADES OF GRASS. I'm shocked. The memory usage is also amazingly low in comparison to previous tests.
After 18 Minutes: The event listener count is the same, never surpassing 154 and the DOM Node Count stays below 25,000 the entire time! There are obviously some things slipping by (some non-backbone components that are still in use, most-likely) but the improvement is astounding.
Conclusion: Prior to this version of Backbone, we were not doing a very good job cleaning up listeners within Backbone itself. The listeners to the DOM were handled fine, but not between models/views/collections. Many of the callbacks involved were tied to Backbone Views which I guess prevented the garbage collector from freeing up the DOM Nodes. Lots of straggling event listeners/callbacks within Backbone (not just binding to the DOM) create a lot of straggling DOM Nodes that can't be garbage collected.
If this isn't a good enough reason to upgrade Backbone, I don't know what is ;o
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