Hi,

I'm sure we've all seen this, and try our best to keep away from conditions that result in it.
Suffice to say, sometimes it cannot be avoided due to the data requirements for some clients, and the design of the user interface.

As an example, we have a page with a large tree on it, from which the system can be configured. We have one for user and security management, and one more for business configuration, counter-parties, assets, that kind of thing.

Tree's are an easy thing to break, performance wise; just add loads of children to a node...

Most of the nodes only have a handful of children, so it's normally fine, but sometimes there is a requirement for a large number of children on a node. Not bonkers-crazy large, but around 400-500 does it.
This is where the trouble starts... I can even break Firefox with a 1000-odd children.

We've changed the design of some areas of the tree where we expect a large amount of data, to either partition the data somehow, or in common or extreme cases have a node with a count on from which a window with a paged grid can be shown.



I'd however like to open a discussion with the view that, if at all possible, the Ext framework should avoid being part of the problem.

The issue can be actively avoided. See this post on stackoverflow, which explains the issue very well.
In short, break up long loops using setTimeout.

A good example of somewhere where things could be improved is NodeInterface's removeAll method.

Now the performance of this method used to be terrible, and was recently improved by Evan.
It, however, is a source of the 'stop running script' popup in IE due to a tight loop.
(As an aside, I'm also confused by it's lack of use of the suppressEvents parameter, it raises events as it sees fit, and silences others).
Code:
                removeAll : function(destroy, suppressEvents, fromParent) {
                    // This method duplicates logic from removeChild for the sake of
                    // speed since we can make a number of assumptions because we're
                    // getting rid of everything
                    var me = this,
                        childNodes = this.childNodes,
                        i = 0,
                        len = childNodes.length,
                        treeStore,
                        node;

                    fromParent = fromParent === true;
                    if (!fromParent) {
                        treeStore = me.store && me.store.treeStore;
                        if (treeStore) {
                            treeStore.beginBulkRemove();
                        }
                    }
                    for (; i < len; ++i) {
                        node = childNodes[i];
                        node.previousSibling = node.nextSibling = node.parentNode = null;
                        me.fireEvent('remove', me, node, false);
                        if (destroy) {
                            node.destroy(true);
                        } else {
                            node.removeAll(false, suppressEvents, true);
                        }
                    }

                    me.firstChild = me.lastChild = null;
                    if (fromParent) {
                        // Removing from parent, clear children
                        me.childNodes = null;
                    } else {
                        // clear array
                        me.childNodes.length = 0;
                    }
                    if (!fromParent) {
                        me.triggerUIUpdate();
                        if (treeStore) {
                            treeStore.endBulkRemove();
                        }
                    }
                    
                    return me;
                },
If this was updated to use the technique mentioned I'm sure it would help.

Obviously the elephant in the room with that one is the fact it's called synchronously, so would need to accept a callback, and everywhere it's used modified. You get the idea though.
I intend to try and prove it helps by doing a few updates... thought I'd post first though, in case I can't make it work, or run out of time.

Anyway, I'm sure there are many places in the framework that could benefit from this approach.

In IE8, with non-minified JS I get the 'stop script' prompt when first loading the application!
Luckily it doesn't happen with built JS (yet), but if it did we'd be in serious trouble... I suspect that's somewhere in the rendering pipeline, but not had to go digging for it yet.

I suspect IE is verging on unsupported in many of the Sencha developers views, but unfortunately those of us who have to sell business applications have to deal with it, and will be stuck with it for many years to come.

The latest grumble from a client is on Windows 7 but using IE8 (which it shipped with) - that's a modern browser for our clients!

Anyway, would welcome some thoughts or comments.

Cheers,
Westy