Performance issues w/jQuery generated code

14 views
Skip to first unread message

Dan G. Switzer, II

unread,
Mar 1, 2011, 11:33:22 AM3/1/11
to ValidateThis
I'm just in the process of evaluating ValidateThis and I've noticed
some real inefficiencies with the jQuery code that's generated.

For each validation method you end up generating code that looks like:

if ($(":input[name='UserName']",$form_frmMain).length) {
$(":input[name='UserName']",$form_frmMain).rules("add", { required :
true, messages: {required: "The Email Address is required."} });
}

This has several issues:

1) Doing lookup via the CSS selector ":input[name=UserName]" is pretty
expensive (especially in older browsers that don't support
document.querySelectorAll().) Because this selector is slow, it's
important to minimize the times you call this selector.

The if() check is actually completely unnecessary in this context. It
actually adds nothing, but performance overhead. If the jQuery object
doesn't then the rules() method won't do anything. So take the if()
statement out completely.

All you need is:

$(":input[name='UserName']",$form_frmMain).rules("add", { required :
true, messages: {required: "The Email Address is required."} });

2) Every time you create a new jQuery object, there's overhead
involved. That means with code like:

if ($(":input[name='UserName']",$form_frmMain).length) {
$(":input[name='UserName']",$form_frmMain).rules("add", { required :
true, messages: {required: "The Email Address is required."} });
}

if ($(":input[name='UserName']",$form_frmMain).length) {
$(":input[name='UserName']",$form_frmMain).rules('add',{"email":
"true","messages":{"email":"Hey, buddy, you call that an Email
Address?"}});
}

You end up creating 4 instances of the exact same object. So, not only
are you creating expensive operations on the selector, you're also
creating jQuery object which have overhead.

The best solution is to either cache all your objects or chain your
methods together.

Unfortunately, the $o.rules("add", {}) call isn't chainable, however
you could create a small plug-in that is:

$.fn.addRule = function (rules){
this.rules("add", rules);
return this;
}

Now you could do:

$(":input[name='UserName']",$form_frmMain)
.addRules({ required : true, messages: {required: "The Email Address
is required."} })
.addRules({"email": "true","messages":{"email":"Hey, buddy, you call
that an Email Address?"}})
;

The benefit here is now you only create a single instance of the
jQuery object which fixes both issues #1 and #2.

However, what might be even a better solution is initiate a cache of
all the jQuery objects you might need in your validation. The benefit
here is that you could use the cached objects instead of the selectors
to speed up code in the validation methods.

Something like this:

// create a cache
function createCache(fields, context){
var cache = {};
for( var i=0; i < fields.length; i++ ) cache[fields[i]] = $
(":input[name='" + fields[i] + "']", context);
return cache;
}

// create all the jQuery objects
var fields = createCache(["UserName", "UserPass", "VerifyPassword",
"UserGroupId"], $form_frmMain);

Now you could do:

fields["VerifyPassword"].rules('add',{"equalTo":
fields["UserPass"],"messages":{"equalTo":"The Verify Password must be
the same as The Password."}});

Instead of:

$(":input[name='VerifyPassword']",$form_frmMain).rules('add',
{"equalTo": ":input[name='UserPass']","messages":{"equalTo":"The
Verify Password must be the same as The Password."}});

Now I haven't looked at the CF code to see how easy/hard these changes
are to make to the framework, but the changes will:

1) Reduce the amount of client-side code being generated
2) Speed up the code

NOTE: The performance issue you gain may be negligible on small forms,
but if you have really large forms you're definitely notice a
difference--especially on older browsers.

Adam Drew

unread,
Mar 1, 2011, 11:41:48 AM3/1/11
to valida...@googlegroups.com
Dan..

You are correct that there are a number of changes that could be made to the client side to improve performance and stability.
We are actively working on a number of client javascript issues and I'm anticipating drastic improvements with the 'next' release.
I know most of what you've mentioned here is being addressed in some way shape or form, however I will review my feature branch to see if you have mentioned anything that might have been missed.

Thanks a lot for the input!

Adam

Bob Silverberg

unread,
Mar 1, 2011, 11:46:37 AM3/1/11
to valida...@googlegroups.com
Thank you so much for your suggestions, Dan. I believe some of these
issues (like the unnecessary if) are a result of the JS evolving over
time and not being re-evaluated, so it's great to have another set of
eyes.

Adam Drew is the unofficial keeper of the JS now, so I'll let him look
at these and consider adding them into the framework. he's currently
doing a fairly major rewrite of the jQuery implementation, so it's
very good timing.

If you have an interest in reviewing the new stuff before it's
released (and we'd love to have you do so), please feel free to join
the ValidateThis-dev list at
https://groups.google.com/group/validatethis-dev. The volume is
pretty low so hopefully it wouldn't be too much of a burden.

Thanks again for your interest and suggestions,
Bob

> --
> You received this message because you are subscribed to the Google Groups "ValidateThis" group.
> To post to this group, send email to valida...@googlegroups.com.
> To unsubscribe from this group, send email to validatethis...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/validatethis?hl=en.
>
>

--
Bob Silverberg
www.silverwareconsulting.com

Dan G. Switzer, II

unread,
Mar 1, 2011, 12:12:36 PM3/1/11
to ValidateThis
Adam,

Let me know if there's something I can do to help or if you have
questions.

I'd also like to see a JS proxy template, instead of loading all the
code inline. That could also prove valuable--but that obviously
increases the complexity a bit.

-Dan

Jamie Krug

unread,
Mar 1, 2011, 12:44:24 PM3/1/11
to valida...@googlegroups.com
On Tue, Mar 1, 2011 at 12:12 PM, Dan G. Switzer, II <dswi...@pengoworks.com> wrote:
I'd also like to see a JS proxy template, instead of loading all the
code inline. That could also prove valuable--but that obviously
increases the complexity a bit.

Dan, this is something I've pondered as well, and I wasn't sure what level of optimization versus complexity might make sense. I thought it might be nice to maybe implement something that's not necessarily core to the framework, but a tool or option to toggle on that would allow optimized JavaScript file(s) to be generated, rather than the inline JS. As with any JavaScript related work, it's often nice to work with readable JS in development, but deploy minified JS to production. If this could be accomplished in a clean way in ValidateThis without getting in the way of the basic setup for newcomers, that would be fantastic.

Best,
Jamie

Bob Silverberg

unread,
Mar 1, 2011, 1:31:23 PM3/1/11
to valida...@googlegroups.com, validate...@googlegroups.com
Folks, I'm going to suggest we move this to the -dev group, as I
imagine that some people on this list aren't interested in this topic.
I'm sending this response to both lists, so please direct your
replies to the -dev list for the remainder of the thread.

I think Jamie's points about readable JS during development are valid,
so we do need to come up with something that could potentially work in
both scenarios. I'm sure you guys will come up with something
awesome. ;-)

Bob

Reply all
Reply to author
Forward
0 new messages