Adding defer to WS Form scripts

Updated on 18 Dec 2023

A defer setting is now available starting with v1.9.178 of WS Form. You might want to toggle that on, especially for new installs. For existing installs, exercise caution and ensure that no functionality is broken.

There is no need to implement this tutorial.


As of version 1.9.177, WS Form (tested the PRO version) does not add a defer attribute to its scripts ws-form.min.js and ws-form-public.min.js that load in the header. This will result in these scripts causing render-blocking.

The plugin does not even load its scripts in the footer (the next best course of action) out of the box, at the very least. The reason cited is apparently to ensure compatibility with performance plugins.

Performance should be the responsibility of individual plugins and not be deferred (pun intended) to other plugins that most users do not use.

A setting to add the defer attribute might be coming in an update to WS Form, but it won’t likely be the default.

Until then, we can fix the situation by adding this code in the child theme’s functions.php (might also work in a code snippets plugin, but we have not tested it):

/**
 * Filter the HTML script tag of listed (by their handles) scripts to add `defer` attribute.
 *
 * @param string $tag    The <script> tag for the enqueued script.
 * @param string $handle The script's registered handle.
 * @param string $src The script’s source URL.
 *
 * @return   Filtered HTML script tag.
 */
add_filter( 'script_loader_tag', function( $tag, $handle, $src ) {
	// if we are in WP admin, abort.
	if ( is_admin() ) {
		return $tag;
	}

	$handles = [
		'ws-form-form-common',
		'ws-form-form-public',
		'ws-form-analytics',
		'ws-form-select',
		'ws-form-tracking',
		'ws-form-conditional'
	];

	if ( in_array( $handle, $handles) ) {
		$tag = str_replace( ' src', ' defer src', $tag );
	}

	return $tag;
}, 10, 3 );

After:

Note: If you use a plugin that relies on WS Form, you are advised to test if all the functionality of your forms is still intact after adding the defer attribute.