12

I'm using jQuery Validate plugin 1.8.0 with jQuery 1.5. Works great for small to medium sized forms. For larger forms the performance degrades significantly (even in IE8 and FF4), sometimes causing the "script is running too slowly" message. It appears that the plugin scans the entire DOM within the form looking for attributes and classes to validate, even if you specified custom rules. Anyone know how to turn this off completely? There is an ignore option as well, but it still would scan the DOM, skipping those with the ignore attr.

Here is what ASP.NET renders, except there are about 120 rows of data. Paging the results is not an option, unfortunately.

<table id="GridView1">
    <tbody>
        <tr>
            <th scope="col">Header 1</th>
            <th scope="col">Header 2</th>
            <th scope="col">Header 3</th>
            <th scope="col">Header 4</th>
            <th scope="col">Header 5</th>
            <th scope="col">Header 6</th>
            <th style="width: 60px; white-space: nowrap" scope="col">Header 7</th>
            <th style="width: 60px; white-space: nowrap" scope="col">Header 8</th>
        </tr>        
        <tr class="gridRow" jquery1507811088779756411="3">
            <td style="width: 50px" align="middle">
                <span id="GridView1_ctl03_Label1">XXX</span>
            </td>
            <td>
                <span id="GridView1_ctl03_Label2">YYY</span>
            </td>
            <td style="width: 50px" align="middle">
                <span id="GridView1_ctl03_Label3">ZZZ</span>
            </td>
            <td align="middle">
                <select style="width: 70px" id="GridView1_ctl03_Dropdown4" name="GridView1$ctl03$Dropdown4">
                    <option selected value="Y">Y</option>
                    <option value="N">N</option>
                </select>
            </td>
            <td style="width: 50px" align="middle">
                <input id="GridView1_ctl03_hidId1" value="100" type="hidden" name="GridView1$ctl03$hidId1" />
                <input id="GridView1_ctl03_hidId2" value="100" type="hidden" name="GridView1$ctl03$hidId2" />
                <input id="GridView1_ctl03_hidId3" value="100" type="hidden" name="GridView1$ctl03$hidId3" />
                <input id="GridView1_ctl03_hidId4" value="100" type="hidden" name="GridView1$ctl03$hidId4" />
                <select style="width: 40px" id="GridView1_ctl03_Dropdown5" name="GridView1$ctl03$Dropdown5">
                    <option selected value="A">A</option>
                    <option value="B">B</option>
                </select>
            </td>
            <td style="width: 50px" align="middle">
                <span id="GridView1_ctl03_Label6">101</span>
            </td>
            <td align="middle">
                <input style="width: 60px" id="GridView1_ctl03_Textbox8" class="date required"
                    title="Please enter a valid start date." type="text" name="GridView1$ctl03$Textbox8"
                    jquery1507811088779756411="122" />
            </td>
            <td align="middle">
                <input style="width: 60px" id="GridView1_ctl03_Textbox9" class="date"
                    title="Please enter a valid end date." type="text" name="GridView1$ctl03$Textbox9"
                    jquery1507811088779756411="123" />
            </td>
        </tr>
    </tbody>
</table>
2
  • Show us your code, a live link, or a demo. Just how big is this form? Commented Apr 4, 2011 at 17:24
  • I put in a code sample (data and control names changed to protect the innocent). There's about 120 rows of data, and I'm really only validating the date fields. It takes about 8-9 seconds to validate the form in IE8. Commented Apr 4, 2011 at 19:44

4 Answers 4

12

I've been struggling with this issue as well. By customizing some of the validation, I've been able to reduce my validation time in IE8 for 80 validating elements from 4100ms to 192ms. I'll post my findings here in the hope that others can benefit, and also in the hope that some expert in jquery-validate will find a problem with my code.

Here are some things that I found helpful:

  1. Make sure you don't have validation attributes on anything you don't actually need to validate. I had some mysteriously showing up on elements - I'm not sure why, but I hard-coded data-val=false on them in my .cshtml to prevent this.
  2. Define your own method to validate the form. The one built in to jQuery does a couple things very slowly, and you likely don't need all the flexibility it provides. Here is mine - using this made a HUGE difference (it's called subset because my form is split up into tabs and I call this on each tab div individually as the user advances).

    jQuery.validator.prototype.subset = function (container, validateHiddenElements) {
        var ok = true;
        var validator = this;
    
        // Performance hack - cache the value of errors(), and temporarily patch the    function to return the cache
        // (it is restored at the end of this function).
        var errors = this.errors();
        var errorsFunc = this.errors;
        this.errors = function () { return errors; };
    
        $(container.selector + " [data-val=true]").each(function () {
    
            !this.name && validator.settings.debug && window.console && console.error("%o has no name assigned", this);
    
            var tagName = this.tagName.toLowerCase();
            if (tagName == "input" || tagName == "select" || tagName == "textarea") {
                var $this = $(this);
    
                if (!$this.hasClass('doNotValidate') &&
                    (validateHiddenElements || $this.is(':visible'))) {
    
                    if (!validator.element($this)) ok = false;
    
                }
            }
        });
    
        this.errors = errorsFunc;
    
        return ok;
    };
    
  3. Define your own showErrors method on validator.settings. The built-in one creates error message spans for each validatable input even when there is no error to display. This gets quite slow if you have a lot of these, so you can add some logic to avoid this. Here is mine:

    function showErrorsOverride() {
        var anyElementsNeedUpdate = false;
        for (var i = 0; i < this.errorList.length; i++) {
            if (!$(this.errorList[i].element).hasClass(this.settings.errorClass)) {
            anyElementsNeedUpdate = true;
            }
        }
        for (var i = 0; i < this.successList.length; i++) {
            if ($(this.successList[i]).hasClass(this.settings.errorClass)) {
                anyElementsNeedUpdate = true;
            }
        }
    
    
        if (anyElementsNeedUpdate) 
        {
            // show the usual errors (defaultShowErrors is part of the jQuery validator)
            this.defaultShowErrors();
        }
    }
    
Sign up to request clarification or add additional context in comments.

3 Comments

Where should I put this??
Just adding a few data-val=false on certain select lists made a HUGE difference for me. Load time down from 34 seconds to just 8.
Helped performance a lot for me but it also replaced all the validation messages I had specified with "This field is required" instead of the message I wanted. That being said removing data-valmsg-replace and storing the message in there on my validation field massively improved performance by myself on my pages
9

A bit late to the party, but for anybody interested - similar to Joe's answer, I found that disabling the success setting from the defaultShowErrors() function helps out quite a bit. All it seems to do is hide the error label for valid fields, and if you don't have any error labels then it is unnecessary overhead. Sped up my form with 55 fields from ~1.8 seconds to ~260ms in IE8.

$(document).ready(function()
{
    $("form").each(function ()
    {
        $(this).data("validator").settings.success = false;
    })
});

2 Comments

Wanted to confirm to others that this setting SIGNIFICANTLY improved my performance. I am validating 1000's of elements and my performance (especially in Firefox) improved from 80+ seconds to approximately 15 seconds! IE 11 showed similar improvement. Disappointingly, Chrome was TERRIBLE. Continually got the "Kill Page" message (which as of today is a known bug). Very, very disappointed in newer versions of Chrome for other web dev as well.
Hi, even later at the party: I am struggling with the same issue: where should I put this piece of code? I tried to put it directly after loading the jquery javascript but it seems to late.
0

We need more code to help you. But traversing DOM objects it's a heavy operation. Maybe for that big forms you want to use another approach. If you are using a lot of combos and textfields you can attach an event handler (on lost focus) so you can save the value in a javascript object and later use this object to get the data.

1 Comment

Traversing the DOM is indeed heavy - I don't think the validate plugin should do that if you are specifying custom rules. I could hand-roll the validation on this form, but I wanted it to be consistent with the rest of the application. I am thinking I might have to customize the validate script myself.
0

We had similar issues with large form but found the following solution. Now our large forms (>600 inputs) validate in ~10ms.

I've posted the answer here: https://stackoverflow.com/a/23132844/1821717

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.