3

The question: How do I go about speeding up the validation, while continuing to use jqBootstrapValidation as my validator?

The problem: I have a small contact form setup really nicely using jqBootstrapValidation as a validator, but when I start adding additional fields it becomes very slow, to the point where if i type multiple characters into a form field it takes the validator over a second to respond.

The slow down can be easily observed with 20-30 form fields.

I have tried: So far I have tried a number of things like hiding elements using style="display: none;", but that seems to make no difference to the speed.

I could process the form in parts before I submit it, but I have not had a lot of luck going about it. Is there a better way to approach this situation, maybe there is something simple that I am missing because I am relatively new to JavaScript?

My current form/js: Works well until we add more form fields.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>My Title</title>
</head>
<body id="page-top" class="index">
    <form name="sentMessage" id="contactForm" novalidate>
        <div class="control-group">
            <label>Name</label>
            <input type="text" placeholder="Name" id="name" required data-validation-required-message="Please a name.">
            <p class="help-block text-danger"></p>
        </div>
        <div class="control-group">
            <label>Message</label>
            <textarea rows="3" placeholder="Message" id="message" required data-validation-required-message="Enter a message."></textarea>
            <p class="help-block text-danger"></p>
        </div>
        <br>
        <div id="success"></div>
        <div>
                <button type="submit">Click to send</button>
        </div>
    </form>

    <!-- jQuery -->
    <script src="js/jquery.js"></script>
    <!-- Contact Form Script -->
    <script src="js/jqBootstrapValidation.js"></script>
    <script>
    $(function() {
        $("#contactForm input,#contactForm textarea").jqBootstrapValidation();
    });
    </script>
</body>
</html>

Validator used: http://ReactiveRaven.github.com/jqBootstrapValidation/

sorifiend
  • 5,927
  • 1
  • 28
  • 45
  • Note: I do use bootstrap to manage my layout, and that's the reason for using jqBootstrapValidation. For the purpose of this question I have stripped out all the bootstrap related code so its easier to approach. – sorifiend Jun 28 '16 at 13:35

1 Answers1

0

I am still looking for a better answer, but in the mean time I have found a work around.

The work around is simply to validate the form only on submission and when certain events happen, and therefore remove all the slow down from an active validator:

The jqBootstrapValidation validator was registered to run validate whenever any of the following events happened keyup, focus, blur, click, keydown, keypress, change, meaning that whenever I was typing in a box a lot of events where happening at the same time and causing huge slow down. The simple fix is simply to remove the events we dont want to trigger and keep the critical ones only.

For example in the jqBootstrapValidation.js file starting at line 431 we can see the different events:

  // =============================================================
  //                                             WATCH FOR CHANGES
  // =============================================================
  $this.bind(
    "submit.validation",
    function () {
      return $this.triggerHandler("change.validation", {submitting: true});
    }
  );
  $this.bind(
    [
      "keyup",
      "focus",
      "blur",
      "click",
      "keydown",
      "keypress",
      "change"
    ].join(".validation ") + ".validation",
    function (e, params) {

So in my case I changed it to only register the "change" and "blur" events like so:

  // =============================================================
  //                                             WATCH FOR CHANGES
  // =============================================================
  $this.bind(
    "submit.validation",
    function () {
      return $this.triggerHandler("change.validation", {submitting: true});
    }
  );
  $this.bind(
    [
      "blur", //validate when a field looses focus
      "change" //Validate on form submit
    ].join(".validation ") + ".validation",
    function (e, params) {

Further testing may be needed to make sure this works as intended.

I think its worth mentioning that this answer https://stackoverflow.com/a/1587543/1270000 also provided additional help with small optimization.

Community
  • 1
  • 1
sorifiend
  • 5,927
  • 1
  • 28
  • 45
  • 1
    Simple trick I'm using a lot is creating a timer (window.setTimeout) that invoke the actual method, and reset that timer in each action that can happen rapidly e.g. keyup. This way the heavy code is triggered only once, e.g. half a second after the last key stroke. The user won't notice any difference, and since it's issued only once, it should be much better. Hope this makes sense. – Shadow The GPT Wizard Jun 28 '16 at 14:56
  • Now that's a seriously smart idea, and that way I wont loose any functionality! Thanks a lot for your input. – sorifiend Jun 28 '16 at 14:58
  • Not 100% sure it will really work in this specific case, but surely worth a try. Let me know how it goes. :-) – Shadow The GPT Wizard Jun 28 '16 at 15:01
  • @ShadowWizard For now I have used my work around, it seemed like a lot of additional work to add the timeout to existing validator code. However if you want to post an answer showing a short stand alone example then I can mark it as accepted. – sorifiend Jun 29 '16 at 14:04
  • Cheers, I'll see if I have time. – Shadow The GPT Wizard Jun 29 '16 at 14:34