6 ms·
> The main culprit after some rudimentary profiling seemed to be the jQuery's .html('') tag. Apparently it does some cleanup which takes awhile on a huge DOM bl
by spicyj 13y ago
> The main culprit after some rudimentary profiling seemed to be the jQuery's .html('') tag. Apparently it does some cleanup which takes awhile on a huge DOM block with lots of attached events. Replaced it with by looping through each child node in the DOM block and removing them with removeChild.
It's important to let jQuery clean up its event handlers, otherwise you'll end up with memory leaks.
- asolove 13y agoThis is important to remember but hopefully not relevant. If you have event handlers on each card instead of delegating them to the container, that's a performance problem all by itself.
- vonseel 13y agoCan you clarify what you mean here? If I were writing a Backbone app, you mean I should bind to data attributes or similar instead of creating a new view for each item in a list?
- asolove 13y agoIf you have a list of thousands of items, attaching event handlers to each of those items separately is relatively expensive, although it makes the view code nicer. If you are as serious about performance as these people, you would want to add delegated events on the parent level. There is a writeup about doing this in Backbone [1] although I can't vouch for it. In fairness, getting really good dom performance out of Backbone is hard because of the lack of built-in delegated event support and the non-synchronized redraws. If you have big apps that need to be super-fast, either read up on dom performance practices and adopt some helper libraries along with Backbone, or try a framework that has its own draw cycle and delegated event support. [1] http://lostechies.com/derickbailey/2011/10/11/backbone-js-getting-the-model-for-a-clicked-element/ http://lostechies.com/derickbailey/2011/10/11/backbone-js-ge...
- crescentfresh 13y ago> getting really good dom performance out of Backbone is hard because of the lack of built-in delegated event support It actually is builtin: https://github.com/jashkenas/backbone/blob/1.1.0/backbone.js#L1072 https://github.com/jashkenas/backbone/blob/1.1.0/backbone.js... In fact it takes a bit of effort to not use event delegation when setting up your events dict.
- asolove 13y agoWell, Backbone handles delegation for elements within the same view. But it doesn't handle the case where you have lots of instances of the same view class in a list and want each handler registered only once for the whole list. You can do this manually by checking out the event target and maintaining a mapping from dom nodes to views, which you ought to do if you have lists of hundreds or thousands of repeated subviews. But Ember and various Backbone plugins can do this for you automatically.
- crescentfresh 13y ago> it doesn't handle the case where you have lots of instances of the same view Wait I'm getting confused. Didn't the title post and your linked article both say not to do this if performance is the goal? (See "Tuesday" in OP). Isn't that what we're talking about here? Sorry if I misunderstood.
- asolove 13y agoYeah, I think this is just a terminology problem. Let's just lay out the complete answer: if you have a list of 1000 things to render in the same way, you can make it faster in various ways: 1. Don't render all of them at once, use pagination or infinite scroll. 2. Don't attach dom events to each item individually, instead attaching one event listener to the list container and having a way to go from the event's target to the appropriate view to act on. 3. Don't even create a view object for each item, just render them with the same template and have a composite view that knows how to act on each item's model for the delegated events. It's important to understand the relative performance benefits of these changes. #1 will make things faster in proportion to how much the page size is smaller the the full list size. #2 will reduce the number of DOM calls by a factor of the number of items in the list. #3 will reduce the number of JavaScript objects created. #2 gets you a 10x-100x bigger speedup than #3. JavaScript fast, DOM slow.
- tracker1 13y agoThis was going to be my comment as well.. better to detach the elements, and put them into a queue to remove completely in a timer loop... this way cleanup happens out of band. I worked on a rather large extjs app, and IE was particularly bad about cleaning up dom objects with events attached, leading to memory leaks so bad that IE <= 8 would need to be reloaded a couple times a day. Firefox at the time was much better, and chrome was really new (so was IE8 at the time). jQuery is good about keeping track of events and properly cleaning up, but it is expensive... though it's easy enough to .find('> *') and detach them, pushing those items into a cleanup queue.