1. #1
    Sencha User
    Join Date
    Sep 2009
    Posts
    13
    Vote Rating
    0
    NateWorcester is on a distinguished road

      0  

    Default Performance Enhancement: Element.removeClass

    Performance Enhancement: Element.removeClass


    I was doing some performance testing of some Ext pages we are building and while profiling I noticed that this function is called A LOT. When I looked at the source, I was baffled at the complexity (cached regex for each class name passed in?) so I wrote this simpler version which outperforms the original (at least in my testing).

    Code:
    Ext.Element.prototype.removeClass = function(className){
    
    	if (!Ext.isArray(className)){
    		className = [className]
    	}
    	
    	if (this.dom && this.dom.className) {
    	
    		var elClasses = this.dom.className.trim().split(" ");
    	
    		for (var i=0, len=className.length; i < len; i++) {
    			elClasses.remove(className[i]);
    		}
    		
    		this.dom.className = elClasses.join(" ");
    	}
            return this;
    }

  2. #2
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    18
    Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough

      0  

    Default


    Could you post your test cases, I'd like to take a look.

  3. #3
    Sencha User
    Join Date
    Sep 2009
    Posts
    13
    Vote Rating
    0
    NateWorcester is on a distinguished road

      0  

    Default


    Sort of a worst case scenario but here it is. I also tested it with just a few classes and it's still faster.

    Code:
    var el = Ext.getBody();
    
    
    var cls = [];
    for (var i = 0; i < 100; i++){
      cls.push("cls-" + i);
    }
    
    for (var i = 0; i < 10; i++){
      el.addClass(cls);
      el.removeClass(cls);
    }
    I profiled it with both IE and firebug profilers. Wish i still had the hard numbers of my big tests but for the worst case scenario above, it was at least 100x faster.

    Here's a smaller set for this one grid im profiling now:
    Original function:
    325 calls - > 752ms
    New Function
    325 calls - > 354ms

  4. #4
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    18
    Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough Jamie Avins is a jewel in the rough

      0  

    Default


    What do you get when you try these:

    Code:
    Ext.Element.prototype.removeClass = function(className){
        var i,
            len,
            elClasses;
        if (!Ext.isArray(className)){
            className = [className];
        }
    
        if (this.dom && this.dom.className) {
            elClasses = this.dom.className.trim().split(" ");
            for (i = 0, len = className.length; i < len; i++) {
                elClasses.remove(className[i]);
            }
            this.dom.className = elClasses.join(" ");
        }
        return this;
    }
    
    Ext.Element.prototype.addClass = function(className){
        var i,
            len,
            v,
            cls = [];
        if (!Ext.isArray(className)) {
            className = [className];
        }
        for (i = 0, len = className.length; i < len; i++) {
            v = className[i];
            if (v && !this.hasClass(v)) {
                cls.push(v);
            }
        }
        if (cls.length) {
            this.dom.className += " " + cls.join(" ");
        }
        return this;
    }

  5. #5
    Ext User
    Join Date
    Apr 2007
    Posts
    3
    Vote Rating
    0
    JoshP is on a distinguished road

      0  

    Default


    Quote Originally Posted by Jamie Avins View Post
    What do you get when you try these:

    Code:
    Ext.Element.prototype.removeClass = function(className){
        var i,
            len,
            elClasses;
        if (!Ext.isArray(className)){
            className = [className];
        }
    
        if (this.dom && this.dom.className) {
            elClasses = this.dom.className.trim().split(" ");
            for (i = 0, len = className.length; i < len; i++) {
                elClasses.remove(className[i]);
            }
            this.dom.className = elClasses.join(" ");
        }
        return this;
    }
    
    Ext.Element.prototype.addClass = function(className){
        var i,
            len,
            v,
            cls = [];
        if (!Ext.isArray(className)) {
            className = [className];
        }
        for (i = 0, len = className.length; i < len; i++) {
            v = className[i];
            if (v && !this.hasClass(v)) {
                cls.push(v);
            }
        }
        if (cls.length) {
            this.dom.className += " " + cls.join(" ");
        }
        return this;
    }
    I tested this on my app and see a tremendous performance gain in IE. Thanks!!

Thread Participants: 2