Advanced Speed Improvements: Load Deferred reCAPTCHA for Contact Form 7

divider

In this post, we will demonstrate an advanced site speed improvement technique by deferring the loading of reCAPTCHA files when using Contact Form 7 for WordPress websites.

[Please note, this technique will not work for Contact Form 7 version 5.2 and beyond. The latest updates to the plugin caused our code to no longer work. However, we are looking into a new method and will update this post when the time comes.]

We have discovered that using certain functionality, like Google’s reCAPTCHA script to fight form spam can actually harm your site speed. The issue is this functionality is dependent on loading numerous third party JavaScript and CSS files preemptively when a form may not even be used by the visitor. This functionality adds extra weight and requests in order for the website to load which is not recommended.

Therefore, our solution was to defer the loading of the reCAPTCHA script until a visitor interacts with the contact form.  Surprisingly, we were unable to find any methods online to accomplish this, so we developed our own technique that we will teach you later in this post.

We also want to demonstrate the performance upgrade you can expect to see after applying our advanced speed improvement technique. If you don’t already know, improving your site speed is beneficial to both your visitors and search engines. Fast loading sites provide visitors with a better user experience and search engines favor faster sites because they can crawl them more efficiently.

Google PageSpeed Insights Score Before and After Speed Technique was Applied

   

Google PageSpeed Insights Diagnostics Before and After Speed Technique was Applied

GTmetrix Page Details Before and After Speed Technique was Applied

Applying this speed improvement technique instantly boosted our overall score (in Google’s PageSpeed Insights) a whopping 16 points which is a huge improvement!

Also, when looking closer at the diagnostics, there was another performance gain. Google is no longer flagging the site to “Reduce the impact of third-party code” or “Reduce JavaScript execution time” which is directly correlated to the reCAPTCHA script being deferred. The update reduced the “main-thread work” execution time by over 3 seconds as well.

Lastly, when looking at the actual metrics regarding fully loaded time, total page size and requests, we can see improvements in each category after the update. The site has a slightly faster load speed, a reduction of 300kb in total page size and 12 less requests made.

How to Perform this Speed Improvement Technique

The first goal is to dequeue the Contact Form 7 script from the site. Within your theme’s functions.php file, simply add the following code.

add_action('wp_print_scripts', function () {
    wp_dequeue_script('google-recaptcha');
});

Just to ensure that the reCAPTCHA script is no longer loading, check the page source of a page on the site. In the footer, it should no longer show this script “https://www.google.com/recaptcha/api.js?render=YOUR_API_KEY&ver=3.0”. Once it is confirmed that the site is successfully dequeueing Contact Form 7’s scripts, we can move onto implementing the load deferring.

Create a new JavaScript file in your theme folder. You can name the file anything you’d like, but I will call it “recaptcha.js”. In this file, insert the code below.

var captchaLoaded = false;

$( document ).ready(function() {

//Load reCAPTCHA script when CF7 form field is focused
$(‘.wpcf7-form input’).on(‘focus’, function() {
// If we have loaded script once already, exit.
if (captchaLoaded)
{
return;
}

// Variable Intialization
console.log(‘reCAPTCHA script loading.’);
var head = document.getElementsByTagName(‘head’)[0];
var recaptchaScript = document.createElement(‘script’);
var cf7script = document.createElement(‘script’);

// Add the recaptcha site key here.
var recaptchaKey = ”;

// Dynamically add Recaptcha Script
recaptchaScript.type = ‘text/javascript’;
recaptchaScript.src = ‘https://www.google.com/recaptcha/api.js?render=’ + recaptchaKey + ‘&ver=3.0’;

// Dynamically add CF7 script
cf7script.type = ‘text/javascript’;

cf7script.text = “!function(t,e){var n={execute:function(e){t.execute(\”” + recaptchaKey +”\”,{action:e}).then(function(e){for(var t=document.getElementsByTagName(\”form\”),n=0;n<t.length;n++)for(var c=t[n].getElementsByTagName(\”input\”),a=0;a<c.length;a++){var o=c[a];if(\”g-recaptcha-response\”===o.getAttribute(\”name\”)){o.setAttribute(\”value\”,e);break}}})},executeOnHomepage:function(){n.execute(e.homepage)},executeOnContactform:function()
{n.execute(e.contactform)}};
t.ready(n.executeOnHomepage),document.addEventListener(\”change\”,n.executeOn
Contactform,!1),document.addEventListener(\”wpcf7submit\”,n.executeOnHomepage,!1)}(grecaptcha,{homepage:\”homepage\”,contactform:\”contactform\”});”;

// Add Recaptcha Script
head.appendChild(recaptchaScript);

// Add CF7 Script AFTER Recaptcha. Timeout ensures the loading sequence.
setTimeout(function() {
head.appendChild(cf7script);
}, 200);

//Set flag to only load once
captchaLoaded = true;
});
});

Now that you have added the JavaScript to the site, the final step (besides testing) is to enqueue our JavaScript file to the site. To do this, go back to your functions.php file and add the following code:

function cf7_defer_recaptcha() {
wp_enqueue_script(‘cf7recap’, get_template_directory_uri() . ‘/recaptcha.js’, array(‘jquery’), ‘1.0’);
}
add_action(‘get_footer’, ‘cf7_defer_recaptcha’);

Now that you have added the JavaScript to the site, the final step (besides testing) is to enqueue our JavaScript file to the site. To do this, go back to your functions.php file and add the following code:

function cf7_defer_recaptcha() {
    wp_enqueue_script('cf7recap', get_template_directory_uri() . '/recaptcha.js', array('jquery'), '1.0');
}
add_action('get_footer', 'cf7_defer_recaptcha');

That should be it for the code. Let’s take a look at the site and test it out! Theoretically, what we should see is the reCAPTCHA script load ONLY when we click into the input field of the form.

Open up your page with the contact form and your inspector tools, and navigate to the network tab.  Let the page load for a few seconds and then click into the Contact Form 7 input field, and you should see the reCAPTCHA script load in, similar to the screenshot below.

Congratulations! You have officially implemented a load defer on Contact Form 7 scripts.

Questions or Feedback?

We would love to hear your feedback if this blog post has helped you to better understand how to make your site faster by deferring the loading of reCAPTCHA for Contact Form 7. Also, if you run into any issues, feel free to leave a comment below and we’ll do our best to help you out with a solution.


20 Responses to Advanced Speed Improvements: Load Deferred reCAPTCHA for Contact Form 7

  1. Rok
    2:27 am on May 7th, 2020

    Hi,
    I tried using your script on my website but I get an error saying
    “Uncaught TypeError: $ is not a function at defer-recaptcha.js?ver=1.0:3”.

    I named the javascript file defer-recaptcha.js instead of recaptcha.js. I also corrected the code in functions.php accordingly.

    What seems to be the problem?

  2. Peter
    6:18 pm on June 7th, 2020

    Deat PaperStreet-Team,
    thanks for the great article, I searched for a solution and found it here.
    Some remarks, maybe they are helpful:
    – I wanted to place the recaptcha.js file in my child theme folder. So I changed “get_template_directory_uri()” to “get_stylesheet_directory_uri()”.
    – Calling the functions in the .js file with “$” did not work. I got errors “Uncaught TypeError: $(…).ready is not a function”. I replaced “$” with “jQuery”, then it worked.

    Thanks again for the great help
    best regards – peter

  3. martin
    6:39 pm on June 18th, 2020

    Hi As you said in your post it all worked as expected, however when using any of the forms on the site they all fail to send the message now?

    Any idea’s as to why?

    Thanks

  4. Pop
    7:44 am on June 20th, 2020

    Thanks! It really worked, and has helped me a lot!

  5. Danielle
    6:11 pm on July 15th, 2020

    Hi there! I recently did this to a site, but I got an error in the console that states that the ‘$’ in line 3 is not a function. How can I fix this?

  6. Gary
    3:28 am on August 7th, 2020

    For those experiencing the $ issue, wordpress does not like that so the easiest solution is replace ‘$’ with ‘jQuery’ such as $(‘.wpcf7-form input’) instead becomes jQuery(‘.wpcf7-form input’)

  7. Olga
    2:58 am on August 12th, 2020

    Hi there,

    I tried this solution and immediately after its implementation everything worked excellent, all parameters improved significantly. Most notably, the warning “Reduce the impact of third-party code” disappeared completely.

    However, when I checked it again with PageSpeed Insights the next day, the speed plummeted from the initial 71 points (desktop) to 54 points (desktop), which was worse than before the implementation. It appears that after some time passed post-implementation, the website got flagged again as “Reduce the impact of third-party code”, this time worse than before.

    Rolled everything back and have now my 70+ points again. Any ideas why?

  8. kanchan
    6:17 am on August 18th, 2020

    When i called it for my recaptcha v2 is saying me grecaptcha function is not define. And what is the use of “homepage” and “contactform ” argument in this.

  9. Floyd Reinhart
    4:12 pm on August 18th, 2020

    $ is not a function. How to fix???

  10. Fajo
    8:58 am on September 15th, 2020

    For WP 5.5.1 + CF7 5.2.2 + ReCaptcha v3 invisible does not work, it is not possible to submit the form.

  11. Thom
    9:54 am on September 17th, 2020

    I got the defer part to work but…..
    When using any of the forms on the site they all fail to send the message now?

    I see that I am not the only one with this problem.
    Do you have a solution for this issue.

  12. Immaginificio
    5:02 am on October 23rd, 2020

    I use CF7 v5.3 and the hidden field for the recaptcha check is named _wpcf7_recaptcha_response and not g-recaptcha-response.

    I’ve replaced \”g-recaptcha-response\” with \”_wpcf7_recaptcha_response\” in the cf7script.text and now it works!

  13. Azharuddin Jadeja
    3:48 pm on October 26th, 2020

    It was working perfectly, but now it’s js not working. Could you help to resolve this?

  14. AMP
    11:08 am on January 8th, 2021

    Immaginificio – thanks for that, was having the same problem. Lifesaver! 😀

    Anyone else having problems after upgrading to a newer version CF7, simply replace:

    g-recaptcha-response

    with

    _wpcf7_recaptcha_response

  15. Mike
    2:19 am on April 22nd, 2021

    Hey, just want to mention that i had to use “wp_deregister_script” instead of “wp_dequeue_script”, to remove the default recaptcha api.js thing.

  16. Chris Lunt
    5:52 pm on May 4th, 2021

    This code worked for me with some tweaks on WP 5.7 and CF7 5.3. Thanks to Immaginificio and Mike for their answers as well, these helped to update the code for me.

    First I had to move the append recaptchaScript line above the cf7script line as the cf7script line requires grecaptcha to be pulled in via the recaptchaScript line.

    I also had to dequeue wpcf7-recaptcha as this had google-recaptcha as a dependency so removing this removed both for me but you could also always remove google-recaptcha just to be safe.

    Hope this helps someone my page speed score went from 24 to 63 on mobile with no caching turned on.

  17. Nils
    2:02 am on May 17th, 2021

    Now THAT is what did the trick in improving my Google Core Web Vitals! Thank you for posting this brilliant hack – a real life-saver. Actually I had to combine all the aspects in the comments in order to get it up and running properly, but afterwards my mobile as well as my desktop performance improved dramatically.

  18. Mark
    2:52 am on May 22nd, 2021

    Can you explain us How we can do it with Gravity Forms plugin please?

  19. Fatih Turan
    3:46 am on August 6th, 2021

    Can anyone share the JS code on the Github Gist?

  20. john Loyd
    2:03 pm on August 23rd, 2021

    thanks to Christ Lunt advice:

    append recaptchaScript line above the cf7script line
    dequeue wpcf7-recaptcha

    and Immaginificio as well on replacing

    g-recaptcha-response with

    _wpcf7_recaptcha_response

    current issue at the moment is, all form submissions are detected as spam and wont submit

Leave a Reply

Your email address will not be published. Required fields are marked *

*