Large and Laggy Gravity Forms
Over at GravityView, I have the pleasure of working on Gravity Forms-related things and sometimes we have a performance issue on our hands. This time it was an issue with a form that has about 15 visible conditional fields, about 300 (yes, three, zero, zero, three hundred :)) hidden calculation fields and a product total at the end.
This form was very laggy in the browser. Any interaction took around 3 seconds to propagate through, blocking the rendering thread completely.
Any click event, keyup event would result in a complete freeze of the browser on this form. Brainstorming began…
Thanks to some great people in the Russian WordPress community, lots of ideas were thrown, most of which “Just rewrite it using X” Carbon Fields, ACF or custom PHP and JavaScript. A rewrite is not good. Gravity Forms was chosen, GravityView went on top of that. Changing the forms now would mean weeks of custom work. Yes, 319 fields is huge, but there must be some other way!
The main idea I was looking at was to locate the heavy function in JavaScript, try to proxy it into the void and only call it when needed. For, example, performance-intensive function expensive_func_a
.
Save it for later var _expensive_func_a = expensive_func_a;
and let it do nothing, like so:
expensive_func_a = function() { /** void */ };
, and way when it’s called by all the events it’s bound to – nothing will really happen.
The function was located using the Performance profiler in Chrome’s Developer tools. Hefty little thing showed the resource gobbler.
Ah. gformCalculateProductPrice
. Fair enough, 300 calculation fields go into calculating the price, all in convoluted JavaScript with deferring, triggering and offloading. Fired up the console and wrote gformCalculateProductPrice = function() {};
. The UI was instantly released, clicking, typing became possible again! Fantastic. But the calculation no longer happened.
The trick here would be do paginated forms then and place the final product pricing fields into the last page. Luckily the form was already broken into multiple pages and all we had to do was to run the noop code that voids the function and let it run on the last page where it’s really needed.
If breaking into multiple pages is not viable for one reason or another, the solution would be to proxy it (_proxy_gformCalculateProductPrice = gformCalculateProductPrice;
), override the Submit button behavior to show “Calculate” first, which calls _proxy_gformCalculateProductPrice();
, renames the button to “Submit” and allows the form to be submitted thereafter. It’s a bit more complicated, especially if the visitor wants to adjust some of the fields to get a lower price.
Either way, the final patch for the slow and laggy form looked like this:
add_action( 'gform_register_init_scripts_' . SLOW_FORM_ID, function( $form ) { // Do not void out on last page if ( rgpost( 'gform_target_page_number_' . SLOW_FORM_ID ) == SLOW_LAST_PAGE ) { return; } ?> <script type="text/javascript"> // Into the void gformCalculateProductPrice = function() {}; </script> <?php } );
Brilliant! The form works, it’s much faster and everyone’s happy 🙂
I also have a very large form tats dynamically driven by a db with alot of conditional sections. its on a vps server but the work can take up to 15 seconds to load. Any ideas on how to make the form faster.
Contact Gravity Forms support to get professional assistance with your installation. Conditionals can suck a lot, though, and probably on the client side. Client side optimizations are hard to get right.
Hi – smart move and interesting, in which file did you put the ‘patch’ code? Would like to try it myself, as I have the same issue.
The hacky fix goes into functions.php, not sure it works with GF 2.3, though.
Hi ,
I have been using Gravity Forms on all my client websites and though they become slow when too many fields are used like in your case but I haven’t found any better alternatives yet.
I also hate the fact that Gravity Forms doesn’t come with a built in styler to make the forms beautiful. I have been using ‘Styles & Layouts for Gravity Forms’ for styling purposes. Let me know about what you think of it.
https://wordpress.org/plugins/styles-and-layouts-for-gravity-forms/
Hey Gennady,
Thanks for writing up this solution. It’s helped us out massively with a couple of huge forms that we use for clients.
One discovery we made recently is that the PHP approach to swapping out the expensive function will only work across pages if you have `ajax=”false”` set in your gravity forms shortcode.
This is because the PHP only runs between pages if the browser is requesting the new page from the server, but with ajax mode turned on, only the extra form data is requested and the `gform_register_init_scripts` action doesn’t trigger.
Adding this here as a note for anyone else who encounters this so there’s a recorded solution.
Thanks again for your work on this, we really appreciate the effort and it’s made a big difference for us.
You’re very welcome. Glad it helped.
n00b question. I am working on a form with the ID of 18. When adding the script, should I replace the verbiage “SLOW_FORM_ID” with “gf_18”? Same with the last page?
Thanks in advance!
You need to
define( 'SLOW_FORM_ID', 18 );
somewhere at the top in this case. Same withSLOW_LAST_PAGE
.Thanks soulseekah for the amazing hack. I’ve been using this for quite some time and it works great with every update of Gravity forms without fail.
My pleasure, mate! Cheers.