views:

559

answers:

3

Hey everyone,

I am trying to troubleshoot why IE is slow slow processing this javascript compared to Chrome and FF. In Chrome and FF there is no delay for any onclick events but in IE it pauses for like 5 seconds before doing anything.

Here is the link to the code i am running.

http://geekswithblogs.net/ptahiliani/archive/2009/08/13/highlighting-textbox-on-error-using-required-field-validator.aspx

I am using this to highlight the color textboxes with errors. It works great, no errors but just soooo slow.

A: 

May be its because it has to invoke an ActiveX to connect server side script. In the place I work we dropped IE support for our WebApplications. Best solution yet to be found ;)

Cem Kalyoncu
can you explain where this is happening in the code in the question link?
Russ Cam
You cant because the code for validator object is not included, however, if it is a server side validation there should be a connection to the server. And in IE use should use MsXMLParser ActiveX control to access network resources. It involves ActiveX object creation which may take time.
Cem Kalyoncu
A: 

It is hard to look at the script and say why it is running slow. Best way to check is to run put some timer log statements to see which part of it is running slow. If you have IE8, you can use the excellent profiler tool that comes with it.

Chetan Sastry
Thats what im looking into now.
chopps
+1  A: 

I don't know much about how this is getting called since it looks like you're using ASP to do that work (and I don't know ASP). But what stands out to me is that you have var inputControl = document.getElementById(Page_Validators[i].controltovalidate); inside of two separate loops.

Multiple calls to document.getElementById for the same elements has been the culprit of many JavaScript performance issues. Consider combining SetValidatorCallouts and ClearValidatorCallouts to reduce the number of calls to document.getElementById (which I'm pretty sure is slower in IE, but can't find any benchmarks at the moment). I'm not saying this will guarantee a massive speed update, but it's 1) worth a shot, and 2) a good practice for JavaScript programming. Something like:

var SetValidatorCallouts = function() {
    var pageValid    = true,
        inputControl = null;

    for ( var i=0; i<Page_Validators.length; i++ ) {
        inputControl = document.getElementById(Page_Validators[i].controltovalidate);              

        if ( !Page_Validators[i].isvalid ) {
            if ( pageValid ) {
                inputControl.focus();
            }

            addClass(inputControl, 'error');
            pageValid = false;                                                    
        } else {
            removeClass(inputControl, 'error');
        }
    }                   

  return pageValid;
}

As a side note, your className modification functions are overly complicated. I would suggest using a standard framework (jQuery, Dojo, ExtJs, etc). Otherwise, consider replacing with the following, simpler methods. These wont necessarily speed up your code, but they will make it easier to maintain, especially since I noticed that you already have special conditions to handle bugs in WebForm_RemoveClassName.

var removeClass = function(element, className) {
    // Simply split on white space and remove the specified class
    var classes = element.className.toLowerCase().split(/\s+/);
    var result  = "";
    className   = className.toLowerCase();

    for ( var i in classes ) {
        if ( classes.hasOwnProperty(i) && classes[i] != className ) {
            // Extra spaces at the end don't matter.  I have yet to see a
            // browser that cares about superfluous whitespace in classes
            result += classes[i] + " ";
        }
    }
    element.className = result;
}

var addClass = function(element, className) {
    // Extra spaces affect nothing, don't bother trying to make 
    // the className attribute perfect.
    element.className += " " + className;
}

A little example of that:

var fakeElement = {
    className: "foo-asdf asdf asdf-foo foo-asdf-asdf fooasdf asdffoo fooasdfasdf asdf fooasdffoo" 
};

console.log(fakeElement.className);
removeClass(fakeElement, "asdf");
console.warn(fakeElement.className);
Justin Johnson
Excellent write up. I will be looking into replacing the getPageElementsByID with jQuery to see if I can squeeze some more performance out of it. I will keep this question updated.
chopps
If you're going to use jQuery, be sure to replace the custom add/remove class functions too.
Justin Johnson
Well...no matter what i did the performance is still slow. I am building a table dynamically and as soon as the TD start to increase the slower it gets. No way around it unfortunately. I am going to search around for other solutions but I might have to can textbox highlighting altogether.
chopps
I haven't seen the code that you're using to build the table, or how big it is, but remember that the `document.getElementsByTagName` and `document.getElementById` methods get slower as the number of DOM nodes inside the base object (in this case `document`) increase. Naturally, this is because more nodes have to be searched. Remember that you can mitigate this by 1) using less markup, and 2) being more specific about the scope of your query (e.g.: `someTableNode.getElementsByTagName('td')` vs `document.getElementsByTagName('td')`). Using less markup is usually your best bet.
Justin Johnson
Hold on, how and when are you building that table dynamically. Some ways of building a table in IE are **significantly** slower than other ways. Could you add more detail to the question with code about when you are building the table and how?
Russ Cam