Largemulti step form loading issue

Hey Guys,

We have created a large multi-step form using the Gravity Form plugin. Now the form is loading very slowly, almost taking 20 seconds. Somewhere i read that, it occurs due to multiple conditions added in gravity form.
So i checked the Gravity form plugin and found the function ‘get_conditional_logic_fields’. It is consuming almost 15 seconds. If we comment full loop within the function then it reduces the time from 20 to 4-5 seconds. But if
we just unset the conditions added in gravity fields to check whether it loads fast without conditions. But no luck, it still takes same time to load form.

I believe it is taking time, as there are multiple loops and after starting $form[‘fields’] loop, again similar loop started in the function. Please check piece of code in form_display.php

if ( is_array( $form['fields'] ) ) {
				foreach ( $form['fields'] as $field ) {
					/* @var GF_Field $field */
					$field->conditionalLogicFields = self::get_conditional_logic_fields( $form, $field->id );
					
					if ( is_array( $submitted_values ) ) {
						$field_value = rgar( $submitted_values, $field->id );

						if ( $field->type === 'consent'
						     && ( $field_value[ $field->id . '.3' ] != GFFormsModel::get_latest_form_revisions_id( $form['id'] )
						          || $field_value[ $field->id . '.2' ] != $field->checkboxLabel ) ) {
							$field_value = GFFormsModel::get_field_value( $field, $field_values );
						}
					} else {
						$field_value = GFFormsModel::get_field_value( $field, $field_values );
					}

					$form_string .= self::get_field( $field, $field_value, false, $form, $field_values );

					if ( $field->layoutSpacerGridColumnSpan && ! GFCommon::is_legacy_markup_enabled( $form_id ) ) {
						$form_string .= sprintf( '<div class="spacer gfield" style="grid-column: span %d;"></div>', $field->layoutSpacerGridColumnSpan );
					}

				}
			}

Function

public static function get_conditional_logic_fields( $form, $fieldId ) {
		$fields = array();

		//adding submit button field if enabled
		if ( isset( $form['button']['conditionalLogic'] ) ) {
			$fields[] = 0;
		}

		foreach ( $form['fields'] as $field ) {

			if ( $field->type != 'page' && ! empty( $field->conditionalLogic ) ) {
				foreach ( $field->conditionalLogic['rules'] as $rule ) {
					if ( intval( $rule['fieldId'] ) == $fieldId ) {
						$fields[] = floatval( $field->id );

						//if field is a section, add all fields in the section that have conditional logic (to support nesting)
						if ( $field->type == 'section' ) {
							$section_fields = GFCommon::get_section_fields( $form, $field->id );
							foreach ( $section_fields as $section_field ) {
								if ( ! empty( $section_field->conditionalLogic ) ) {
									$fields[] = floatval( $section_field->id );
								}
							}
						}
						break;
					}
				}
			}
			//adding fields with next button logic
			if ( ! empty( $field->nextButton['conditionalLogic'] ) ) {
				foreach ( $field->nextButton['conditionalLogic']['rules'] as $rule ) {
					if ( intval( $rule['fieldId'] ) == $fieldId && ! in_array( $fieldId, $fields ) ) {
						$fields[] = floatval( $field->id );
						break;
					}
				}
			}
		}

		return $fields;
	}```

As we have almost 3000-4000 in the form,
Is there any way to override this function or form_display.php ?

Thanks

Hey Guys,

I modified the code in form_display.php to load the form faster. I know it is not recommended as for future updates, but there is no way to override or modify GFFormDisplay class ( form_display.php ).

Thanks

Hi, Parambir,

Unfortunately, there is not a way to override that function or form_display.php. Could you share the changes you made to form_display.php? It is possible that we could implement your solution in a future release of the plugin.

Meanwhile, forms as large as yours can cause performance problems, and can also be a lot of work for your users to fill out. Instead of altering form_display.php, another solution might be to break your form up into multiple forms: instead of one form with a lot of conditional fields, you could have several forms, and when a user fills out one, they are redirected to another form depending on their answers in the first one. Or you might take a look at Nested Forms from Gravity Wiz: Gravity Forms Nested Forms | Gravity Forms Repeater Add-on | Gravity Wiz I am not sure how the performance of Nested Forms compares, but it might help. I realize that splitting up your form might not be a practical solution, but it’s worth considering.

Thank you!

Hi Morgan.
Thanks for your response.

As per your recommendations, it is not possible to break the form into multiple forms or use add-ons at this stage. Our forms have 2400+ fields and we added conditions on 270 fields. Forms are just slowing down because of the conditional loop block ( form_display.php ).

It will be great if you can implement the solution in a future release.
The solution that we implemented is:

  1. Created a table with fields - id (PK), form_id, ardata (longtext), created_at.
    ardata column is used to saved conditions.
    form_id is gravity form id.

  2. When admin create/update form in admin, we call gravity form in the background to save conditions in the database table ( as we added 2 functions in form_display.php ) .

  3. In form_display.php file, we take conditions from the database table ( instead to go into nested loops and generate conditions at runtime).

Here is the customized file link ( form_display.php ): WeTransfer - Send Large Files & Share Photos Online - Up to 2GB Free

As admin can also change conditions or modify the form, so for that we are using hook gform_after_save_form to regenerate conditions and save them back in the database table. Here is the code that we added in our own plugin.

// Gravity form create or update hook
		add_action( 'gform_after_save_form', array($plugin_admin, 'after_gform_after_save_form_admin'), 10, 2);

		//Custom hook to redraw gform in background - It will save conditions
		add_action( 'call_gform_to_add_conditions', array($plugin_admin, 'function_gform_to_add_conditions'), 10, 1)

And functions are defined here:

public function after_gform_after_save_form_admin( $form, $is_new ){		
		// This is just to add latest conditions back in table
		wp_schedule_single_event( time(), 'call_gform_to_add_conditions', array( $form["id"] ) );		
	}

	public function function_gform_to_add_conditions( $form_id ){
		global $wpdb;		
		$gform_conditions = $wpdb->prefix.'gform_conditions';		
		$existdata = $wpdb->get_row( $wpdb->prepare("SELECT id FROM $gform_conditions WHERE form_id = %d", $form_id) );
		if ( !empty( $existdata ) ){
			$wpdb->query( $wpdb->prepare( "UPDATE $gform_conditions SET ardata = '' WHERE form_id = %d",  $form_id ) );
		}			
		gravity_form( $form_id );
	}

Thanks

Thank you for sharing all of those details, Parambir! We are considering making some updates to how conditional logic works, and we will take your performance concerns and your code suggestions into consideration when we work on that!

2 Likes